boot.artboot.oat
external/vogar/src/vogar/ModeId.java: // $BOOTCLASSPATH defined by system/core/rootdir/init.rc
而在~/android-6.0.1_r62/out/target/product/generic/root/init.rc中有:
7 import /init.environ.rc
在~/android-6.0.1_r62/out/target/product/generic/obj/ETC/init.environ.rc_intermediates/init.environ.rc中:
10 export BOOTCLASSPATH /system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/apache-xml.jar:/system/framework/org.apache.http.legacy.boot.jar
将以上这些jar编译成boot.art(image文件)和boot.oat(可执行文件)。
其中/system/framework/framework.jar等jar包中的类在framework/base/preloaded-classes中有定义,其注释为:
1 # Classes which are preloaded by com.android.internal.os.ZygoteInit.
其中关于telephony的类:
130 [Lcom.android.internal.telephony.PhoneConstants$State;...
1590 android.telephony.CarrierConfigManager
1591 android.telephony.PhoneNumberUtils
1592 android.telephony.Rlog
1593 android.telephony.SubscriptionManager
1594 android.telephony.TelephonyManager...
2281 com.android.internal.telephony.ISub
2282 com.android.internal.telephony.ISub$Stub
2283 com.android.internal.telephony.ISub$Stub$Proxy
2284 com.android.internal.telephony.ITelephony
2285 com.android.internal.telephony.ITelephony$Stub
2286 com.android.internal.telephony.ITelephony$Stub$Proxy
2287 com.android.internal.telephony.ITelephonyRegistry
2288 com.android.internal.telephony.ITelephonyRegistry$Stub
2289 com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
2290 com.android.internal.telephony.PhoneConstants$State
以上类均位于./base/telephony/java/com/android/internal/telephony和./base/telephony/java/android/telephony中
preloaded-classes中有:
2676 dalvik.system.BaseDexClassLoader
2677 dalvik.system.BlockGuard
2678 dalvik.system.BlockGuard$1
2679 dalvik.system.BlockGuard$2
2680 dalvik.system.BlockGuard$BlockGuardPolicyException
2681 dalvik.system.BlockGuard$Policy
2682 dalvik.system.CloseGuard
2683 dalvik.system.CloseGuard$DefaultReporter
2684 dalvik.system.CloseGuard$Reporter
2685 dalvik.system.DalvikLogHandler
2686 dalvik.system.DalvikLogging
2687 dalvik.system.DexFile
2688 dalvik.system.DexFile$DFEnum
2689 dalvik.system.DexPathList
2690 dalvik.system.DexPathList$Element
2691 dalvik.system.PathClassLoader
2692 dalvik.system.SocketTagger
2693 dalvik.system.SocketTagger$1
2694 dalvik.system.VMDebug
2695 dalvik.system.VMRuntime
2696 dalvik.system.VMStack
2697 dalvik.system.ZygoteHooks
以上类定义在:~/android-6.0.1_r62/libcore/dalvik/src/main/java/dalvik/system中。
可以参见:
preload-classes的前世今生:
http://blog.csdn.net/lusing/article/details/50611335
关于preloaded-classes:
//~/android-6.0.1_r62/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
565 public static void main(String argv[]) {...
590 registerZygoteSocket(socketName);
591 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
592 SystemClock.uptimeMillis());
593 preload();
594 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
595 SystemClock.uptimeMillis());...
622 }
在Zygote初始化的时候,会调用到ZygoteInit的main方法。在注册了ZygoteSocket的控制通道之后,就调用preload方法去加载一些预加载的数据。
180 static void preload() {
181 Log.d(TAG, "begin preload");
182 preloadClasses();
183 preloadResources();
184 preloadOpenGL();
185 preloadSharedLibraries();
186 preloadTextResources();
187 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
188 // for memory sharing purposes.
189 WebViewFactory.prepareWebViewInZygote();
190 Log.d(TAG, "end preload");
191 }
继续看其中的preloadClasses()函数的实现:
210 /**
211 * Performs Zygote process initialization. Loads and initializes
212 * commonly used classes.
213 *
214 * Most classes only cause a few hundred bytes to be allocated, but
215 * a few will allocate a dozen Kbytes (in one case, 500+K).
216 */
217 private static void preloadClasses() {
218 final VMRuntime runtime = VMRuntime.getRuntime();
219
220 InputStream is;
221 try {
222 is = new FileInputStream(PRELOADED_CLASSES);
223 } catch (FileNotFoundException e) {
224 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
225 return;
226 }...
is = new FileInputStream(PRELOADED_CLASSES) :打开PRELOADED_CLASSES文件,读取文件内容。
其中PRELOADED_CLASSES的定义为:
94 /**95 * The path of a file that contains classes to preload.96 */97 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
继续看preloadClasses函数:
255 try {
256 BufferedReader br
257 = new BufferedReader(new InputStreamReader(is), 256);
258
259 int count = 0;
260 String line;//readLine返回的是该reader的可用的text的next line或者null。
261 while ((line = br.readLine()) != null) {
262 // Skip comments and blank lines.//trim()函数是去掉字符串首尾的空格
263 line = line.trim();//下面是去掉注释的#开头的line和空白行。
264 if (line.startsWith("#") || line.equals("")) {
265 continue;
266 }
267
268 try {
269 if (false) {
270 Log.v(TAG, "Preloading " + line + "...");
271 }
272 // Load and explicitly initialize the given class. Use
273 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
274 // (to derive the caller's class-loader). Use true to force initialization, and
275 // null for the boot classpath class-loader (could as well cache the
276 // class-loader of this class in a variable).
277 Class.forName(line, true, null);
278 count++;
279 } catch (ClassNotFoundException e) {
280 Log.w(TAG, "Class not found for preloading: " + line);
281 } catch (UnsatisfiedLinkError e) {
282 Log.w(TAG, "Problem preloading " + line + ": " + e);
283 } catch (Throwable t) {
284 Log.e(TAG, "Error preloading " + line + ".", t);
285 if (t instanceof Error) {
286 throw (Error) t;
287 }
288 if (t instanceof RuntimeException) {
289 throw (RuntimeException) t;
290 }
291 throw new RuntimeException(t);
292 }
293 }
读取PRELOADED-CLASSES文件中的内容,并用Class.forName函数对每个类进行加载。
继续:
294
295 Log.i(TAG, "...preloaded " + count + " classes in "
296 + (SystemClock.uptimeMillis()-startTime) + "ms.");
297 } catch (IOException e) {
298 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
299 } finally {
300 IoUtils.closeQuietly(is);
301 // Restore default.
302 runtime.setTargetHeapUtilization(defaultUtilization);
303
304 // Fill in dex caches with classes, fields, and methods brought in by preloading.
305 runtime.preloadDexCaches();
306
307 // Bring back root. We'll need it later if we're in the zygote.
308 if (droppedPriviliges) {
309 try {
310 Os.setreuid(ROOT_UID, ROOT_UID);
311 Os.setregid(ROOT_GID, ROOT_GID);
312 } catch (ErrnoException ex) {
313 throw new RuntimeException("Failed to restore root", ex);
314 }
315 }
316 }
317 }
接下来再看WritePreloadedClassFile类,在~/android_change/frameworks/base/tools/preload/WritePreloadedClassFile.java中,由于该类的作用就是writes /frameworks/base/preloaded-classes. Also updates {@link LoadedClass#preloaded} fields and writes over compiled log file.
里面两个关键变量为:
32 /**33 * Preload any class that take longer to load than MIN_LOAD_TIME_MICROS us.34 */35 static final int MIN_LOAD_TIME_MICROS = 1250;36 37 /**38 * Preload any class that was loaded by at least MIN_PROCESSES processes.39 */40 static final int MIN_PROCESSES = 10;
boot.artboot.oat相关推荐
- Android执行时ART载入OAT文件的过程分析
在前面一文中,我们介绍了Android执行时ART,它的核心是OAT文件.OAT文件是一种Android私有ELF文件格式,它不仅包括有从DEX文件翻译而来的本地机器指令.还包括有原来的DEX文件内容 ...
- android运行时ART加载OAT文件解析
在前面一文中,我们介绍了Android运行时ART,它的核心是OAT文件.OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容 ...
- boot.oat FC问题分析报告
[NE现场] pid: 5252, tid: 5252, name: ndroid.contacts >>> com.android.contacts <<< si ...
- odex to dex boot.oat
更新 Android 5.x (Lollipop) 之后的 framework/services.jar 星期三, 2015-12-30 10:05 - qyb 先记录一下,https://githu ...
- 老罗android oat,入门ART虚拟机(5)——OAT文件
Android安全交流群:478084054 先贴老罗的一张图: 再摘一段老罗的描述:"作为Android私有的一种ELF文件,OAT文件包含有两个特殊的段oatdata和oatexec,前 ...
- android oat如何提取dex文件字节码,Android: 使用oatdump反编译oat文件
网上经常看到有通过apktool将apk中的dex反编译成smali格式的文件,以便分析功能实现与破-解,确没怎么看到oat文件反通过oatdump反编译的,所以就写了一篇这样的文档.声明一下oat文 ...
- ART加载OAT文件的分析
本文对老罗博客http://blog.csdn.net/luoshengyang/article/details/39307813 进行学习理解,针对android6.0系统源码,连个人理解带复制粘贴 ...
- Android ART Oat文件格式简析(下)
在上篇中,我们分析到了OatFile的begin_和end_变量分别被指定到了符号oatdata和oatlastword指定的位置.那么指定的这一段数据到底是什么呢?本文会接下来分析. 首先来看Oat ...
- Android ART Oat文件格式简析(上)
前面写了一篇博客大致描述了一下Image文件的结构,本文将接下来简单描述一下Oat文件的大致结构. 和前面一样,还是来看一下代码,代码非常复杂,为了保证大家不分心,我会尽量去除一些冗余的部分,只留下主 ...
最新文章
- 东软java实训第一个项目人力资源管理
- POJ1279(求多边形内核的面积)
- 深入理解Go底层原理剖析 (送书)
- 在64位系统上注册并使用32位的COM组件
- new String(123) 创建了几个对象?
- RocketMQ如何动态扩容和缩容
- 遍历一个文件下的所有目录和文件
- CentOS 内核升级的总结
- Java实现Redis的消息订阅和发布
- 解决webstorm out of memory内存不足问题
- hdu 1099 Lottery
- 看_那人好像一个产品狗_对_这就是产品狗
- 什么是大数据与智能数据?什么是惯性测量单元与GNSS?
- CprimePlus 函数2
- linux桌面应用小结,Linux桌面应用技巧大全
- 怎么从身份证号码批量提取出生年月日?
- 【猿码】java swing实现喜羊羊与灰太狼推箱子游戏附带视频开发教程可做为Java毕设大作业
- CentOS7.6系统安装步骤
- 为何企业级架构日益盛行?
- sso单点登录的PHP实现(Laravel框架)
热门文章
- 大数据开发是干什么的?
- 13,21,24.over
- 使用asp.net开发钉钉群机器人全过程
- 微信登录服务器封号,微信正式宣布封号标准,已有大量账号被封停,你有没有“踩雷”?...
- 正负数二进制表示,正负数二进制移位运算、二进制源码、反码、补码
- 什么服务器适合做电商网站
- linux访问vdma的数据,12_数据通路笔记一_DDR_VDMA_VGA
- iOS图片处理-去掉背景色,截取有内容部分
- 在线办公市场竞争加剧,百度如流锚定“知识管理”,生态联动大有可为
- 【论文译文】NICE