anrԴ??
概述
在线监控发现OOM涨幅较大,定位修复内存泄漏和大对象占用问题后,仍未能达到正常标准。在新上报的hprof文件中发现,几乎所有案例中都有名为FinalizerReference的对象,数量庞大,抽奖源码 后台设置内存占用高居榜首,判断其为引起OOM上涨的主因。
ReferenceQueue
ReferenceQueue是一个存放Reference对象的队列,当Reference对象所引用的对象被GC回收时,该Reference对象会被加入到引用队列中。例如,创建一个bean强引用与一个reference软引用,当bean被回收时,软引用reference对象会被加入queue队列,开发者需自行处理。Leakcanary检测内存泄漏原理基于应用的云购限购源码ReferenceQueue引用队列,例如Activity的引用队列。
FinalizerReference
介绍Finalizer对象,指在其Java类中复写了finalize()方法且非空的对象,称作f类。类加载过程中会标记加载的Java类是否为f类。
FinalizerReference概述
FinalizerReference是协助FinalizerDaemon线程处理对象finalize()工作的工具。它通过FinalizerReference类创建链表,每个FinalizerReference对象使用ReferenceQueue创建,当对应对象Object referent被回收后,该FinalizerReference会放入ReferenceQueue。
FinalizerReference.add
FinalizerReference.add方法由虚拟机调用,创建对象时发现该类为f类,调用此方法创建FinalizerRefence对象并加入到头链表中。
FinalizerReference.remove
当f类对象发生GC时,其对应的FinalizerReference对象会被加入FinalizerReference.queue队列,remove时机与FinalizerDaemon守护线程相关。导航带新闻源码FinalizerDaemon.runInternal方法通过queue的poll/remove方法获取queue中的Reference引用,执行doFinalize方法调用Finalizer对象的finalize()方法。
小结
FinalizerReference主要协助FinalizerDaemon线程执行Finalizer对象的finalize()方法。
ReferenceQueueDaemon
FinalizerDaemon守护线程已介绍,这里再看ReferenceQueueDaemon守护线程。创建引用对象时可以关联一个ReferenceQueue队列,被引用对象被GC回收时,该reference对象会被加入其关联队列。加入队列操作由ReferenceQueueDaemon守护线程完成。
FinalizerWatchdogDaemon
补充FinalizerWatchdogDaemon守护线程,与FinalizerDaemon和ReferenceQueueDaemon线程一同启动。FinalizerDaemon和ReferenceQueueDaemon线程的runInternal方法中,monitoringNotNeeded方法休眠线程停止timeout计时,此方法唤醒FinalizerWatchdogDaemon守护线程。FinalizerWatchdogDaemon监控两种执行时长:FINALIZER_DAEMON和RQ_DAEMON,执行超时抛出TimeOutException异常,vs如何调入源码避免在finalize()方法中执行耗时操作。
OOM排查
排除大对象和内存泄漏后,在hprof中发现大量X(业务上的某个对象)堆积,X对象对应Java类与Native层有关,重写了finalize()方法,线下无法复现X对象堆积路径。可能的业务场景代码逻辑不当导致X对象疯狂创建,导致FinalizerDaemon线程回收不及时。通过显式调用系统gc和runFinalization方法,发现子线程调用无效,主线程调用导致ANR。查看ANR堆栈发现问题源于某个finalize()方法调用的Native代码卡死,逻辑问题导致死锁,阻塞FinalizerDaemon线程执行,引起对象堆积。
总结
Java中finalizer()实现了类似析构函数的二八杠俱乐部源码概念,可以在对象被回收前执行回收性操作。f类使用不当可能导致问题,避免重载finalizer()方法,通过逻辑接口释放内存,避免频繁创建或大型对象通过finalizer()释放,以防出现相关问题。
相关守护线程有四个,可深入查看源码。
线上监控时,可能还需优化UI渲染、奔溃、卡顿、体积包、网络、存储等,整理成脑图。
内功修炼需持续不断,性能优化同样需要坚持。
了解android的framework层对工作有什么帮助吗?
掌握Android框架层的知识对开发者来说至关重要。深入理解框架层,能让你在进行性能优化、监控应用状态、调用API等工作中更加得心应手。
比如在监控应用性能时,了解掉帧、ANR(应用程序无响应)、启动监控等机制,需要对框架层有深入理解。这包括知道如何利用机制进行监控,选择正确的监控点,以及通过反射等技术实现监控。
在调用API时,往往Android框架层已经为应用提供了丰富的接口,但如果对这些机制的原理了解不深,很难在此基础上进行优化。例如,在优化应用启动速度时,需要定制合适的StartingWindow,合理处理宽高、DelayLoad的时机,以及Service和Activity的启动策略。
Handler、MessageQueue、Looper等概念,对Android开发者来说至关重要。通过源码深入理解这些机制,有助于更好地理解ThreadLocal、线程与Handler的关系,以及避免在子线程更新UI等常见问题。此外,ContentProvider、Broadcast、Service等组件如何利用Message进行ANR监控,也是深入学习的重点。
进程管理机制同样值得深入研究。了解Android系统如何通过AMS(ActivityManagerService)对进程进行优先级设置和内存管理,可以提高应用的存活率。掌握这些机制有助于开发者优化资源分配,提升应用性能。
在使用Activity启动模式时,除了熟练应用各种模式,了解Activity栈和Task的管理机制,能够帮助开发者更深入地理解启动模式的使用场景和限制。
关于View的Hardware Layer,理解其实现机制对于优化动画性能至关重要。知道何时将View设置为硬件加速模式以及如何在动画前后切换,可以帮助开发者在不同场景下实现最佳性能。
在处理卡顿和掉帧问题时,深入理解Choreographer、VSync、SurfaceFlinger、Binder等组件的工作原理,能够帮助开发者更全面地分析和解决性能问题。掌握这些知识有助于在不同场景下优化应用性能,特别是在高帧率渲染、低内存环境以及多线程通信等场景中。
综上所述,深入学习Android框架层的知识,不仅能够提升开发者对现有技术的理解,还能够促进在性能优化、系统监控和API使用等方面取得突破。通过阅读源码,开发者可以更全面地掌握Android系统的内部运作机制,从而在实际开发中实现更高效、更稳定的应用。
Android N å大ç»ä»¶çå·¥ä½åç
æ¬æ侧é讲解android N ç³»ç»ä¸å大ç»ä»¶çå·¥ä½åçï¼ä¸åç³»ç»åçç¥æå·®å«ãéè¿åæå大ç»ä»¶çå·¥ä½æµç¨å 深对Android Frameworkçç解ï¼ä¹ä¸ºæ件åå¼åæä¸åºç¡ã
Activity
å±ç¤ºä¸ä¸ªçé¢å¹¶åç¨æ·äº¤äºï¼å®æ®æ¼çæ¯ä¸ä¸ªåå°çé¢çè§è²ã
Service
计ç®åç»ä»¶ï¼ç¨äºåå°æ§è¡ä¸ç³»å计ç®ä»»å¡ï¼å·¥ä½å¨ä¸»çº¿ç¨ï¼èæ¶æä½éè¦å¦èµ·çº¿ç¨ï¼ å为å¯å¨ç¶æåç»å®ç¶æã
BroadcastReceiver
æ¶æ¯åç»ä»¶ï¼ä¸»è¦ç¨äºä¸åç»ä»¶æè ä¸ååºç¨ä¹é´çæ¶æ¯ä¼ éï¼å®å·¥ä½å¨ç³»ç»å é¨ï¼ä¸éåæ§è¡èæ¶æä½ï¼æä½è¶ è¿5sï¼ä¼åºç°ANRã
ContentProvider
æ°æ®å ±äº«åç»ä»¶ï¼ç¨äºåå ¶ä»ç»ä»¶æè åºç¨å ±äº«æ°æ®ï¼ä¸»è¦æ§è¡CURDæä½ã
æ们å¯å¨ä¸ä¸ªactivityæ两ç§æ¹æ³ï¼
第ä¸ç§ï¼Activityç´æ¥å¯å¨æ¹å¼ï¼ï¼
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
第äºç§ï¼Contextå¯å¨æ¹å¼ï¼
Intent intent = new Intent(this, MainActivity.class);
getApplicationContext().startActivity(intent);
ä¸åçå¯å¨æ¹å¼Activityçå·¥ä½æµç¨æç¹å·®å«ã
两ç§å¯å¨é½ä¼è°ç¨å°Instrumentationç±»ä¸çexecStartActivityçæ¹æ³ï¼ç³»ç»æç»æ¯éè¿ActivityThreadä¸çperformLaunchActivityå®æActivityçå建åå¯å¨ã
performLaunchActivityæ¹æ³ä¸»è¦å®æ以ä¸å·¥ä½ï¼
1ãéè¿ActivityClientRecord对象è·åå¯å¨activityçç»ä»¶ä¿¡æ¯
2ãéè¿mInstrumentation对象çnewActivityæ¹æ³è°ç¨classloaderå®æactivityçå建
3ãéè¿r.packageInfo(LoadedApk 对象)çmakeApplicationæ¹æ³å°è¯å建Application对象
4ãå建ContextImpl对象并è°ç¨Activityçattachæ¹æ³å®æä¸äºæ°æ®çåå§å
5ãè°ç¨ActivityçonCreateæ¹æ³
å¨Activityå¯å¨çè¿ç¨ä¸ï¼Appè¿ç¨ä¼é¢ç¹å°ä¸AMSè¿ç¨è¿è¡éä¿¡ï¼
Appè¿ç¨ä¼å§æAMSè¿ç¨å®æActivityçå½å¨æç管ç以åä»»å¡æ ç管çï¼è¿ä¸ªéä¿¡è¿ç¨AMSæ¯Server端ï¼Appè¿ç¨éè¿ææAMSçclient代çIActivityManagerå®æéä¿¡è¿ç¨ï¼
AMSè¿ç¨å®æçå½å¨æ管ç以åä»»å¡æ 管çåï¼ä¼ææ§å¶æ交ç»Appè¿ç¨ï¼è®©Appè¿ç¨å®æActivity类对象çå建ï¼ä»¥åçå½å¨æåè°ï¼è¿ä¸ªéä¿¡è¿ç¨ä¹æ¯éè¿Binderå®æçï¼Appæå¨server端çBinder对象åå¨äºActivityThreadçå é¨ç±»ApplicationThreadï¼AMSæå¨clientéè¿ææIApplicationThreadç代ç对象å®æ对äºAppè¿ç¨çéä¿¡ã
Serviceæ两ç§å¯å¨æ¹å¼ï¼startService()åbindService()ï¼ä¸¤ç§ç¶æå¯ä»¥å¹¶å:
startServiceæµç¨
bindServiceæµç¨
BroadcastReceiverçå·¥ä½è¿ç¨ä¸»è¦å æ¬å¹¿æç注åãåéåæ¥æ¶:
å¨æ注åè¿ç¨ï¼
åéè¿ç¨
éæ注åæ¯ç±PackageManagerServiceï¼PMSï¼å¨åºç¨å®è£ çæ¶åå®ææ´ä¸ªæ³¨åè¿ç¨çï¼é¤å¹¿æ以å¤ï¼å ¶ä»ä¸å¤§ç»ä»¶ä¹é½æ¯å¨åºç¨å®è£ æ¶ç±PMS解æ并注åçã
æ¯ä¸ªè¿ç¨çå ¥å£é½æ¯ActivityThead.main()ï¼Appçå¯å¨æµç¨å¦ä¸ï¼
ä»æºç ä¸å¯ä»¥çåºï¼
åºç¨å¯å¨çå ¥å£ä¸ºActivityThreadçmainæ¹æ³ï¼mainæ¹æ³ä¼å建ActivityThreadå®ä¾å¹¶å建主线ç¨æ¶æ¯éåã
attachæ¹æ³ä¸è¿ç¨è°ç¨AMSçattachApplicationæ¹æ³ï¼å¹¶æä¾ApplicationThreadç¨äºåAMSçéä¿¡ã
attachApplicationæ¹æ³ä¼éè¿bindApplicationæ¹æ³åHæ¥è°åActivityThreadçhandleBindApplicationï¼è¿ä¸ªæ¹æ³ä¼å å建Applicationï¼åå è½½ContentProviderï¼ç¶åæä¼åè°ApplicationçonCreateæ¹æ³ã
ç±ä¸å¾å¯ä»¥çåºï¼å¨ContentProviderçå¯å¨è¿ç¨ä¸ä¼´éçappè¿ç¨çå¯å¨ã
ContentProviderçå ¶ä»CURDæä½å¦insertï¼deleteï¼updateè·queryçæµç¨ç±»ä¼¼ã
2024-11-20 07:15
2024-11-20 06:53
2024-11-20 06:44
2024-11-20 06:16
2024-11-20 06:15