IT评测·应用市场-qidao123.com技术社区

标题: Android性能优化之内存泄漏优化(工具篇) [打印本页]

作者: tsx81429    时间: 2024-9-3 11:16
标题: Android性能优化之内存泄漏优化(工具篇)
Android 内存泄漏指的是应用程序在运行过程中,因为一些原因导致不再使用的对象无法被垃圾回收器回收,从而使得这些对象占用的内存无法释放,终极导致内存占用逐渐增加,大概导致应用程序的性能下降、响应变慢甚至瓦解。
一、Android Memory Profiler

官方文档:https://developer.android.com/studio/profile/memory-profiler
内存性能分析器是 Android Profiler 中的一个组件,可帮助您识别大概会导致应用卡顿、冻结甚至瓦解的内存泄漏和内存抖动。它表现一个应用内存使用量的实时图表,让您可以捕获堆转储、强制执行垃圾回收以及跟踪内存分配。

如需打开内存分析器,请按以下步骤利用:
假如存在内存泄漏,应用在转到后台运行时,仍大概保留相应内存。此行为会导致系统强制执行不须要的垃圾回收事件,因而拖慢系统别的部分的内存性能。终极,系统将被迫终止您的应用进程以回收内存。然后,当用户返回您的应用时,它必须完全重启。
为帮助防止这些题目,您应使用内存分析器执行以下利用:

捕获堆转储
堆转储表现在您捕获堆转储时您的应用中哪些对象正在使用内存。特别是在长时间的用户会话后,堆转储会表现您认为不应再位于内存中却仍在内存中的对象,从而帮助识别内存泄漏。
捕获堆转储后,您可以查看以下信息:

如需捕获堆转储,请点击 Capture heap dump,然后选择 Record。在转储堆期间,Java 内存量大概会暂时增加。 这很正常,因为堆转储与您的应用发生在同一进程中,并需要一些内存以网络数据。
在分析器捕获堆转储后,内存分析器界面将转换到表现堆转储的单独屏幕。

如需检查您的堆,请按以下步骤利用:


在您的堆转储中,请注意由下列任意情况引起的内存泄漏:

二、Memory Analyzer (MAT)

官网:https://eclipse.dev/mat/

- 主宰树(Dominator Tree)
Dominator Tree 列出了最大的对象。我们可以将其称为“Keep-Alive Tree”,因为下一级表现了那些立刻被制止进行垃圾回收的对象。右键单击以深入查看:查看传出和传入引用,或查看 GC 根的路径以查看使对象保持运动的引用链。





三、LeakCanary

官网:https://square.github.io/leakcanary/

Gradle 配置
  1. dependencies {
  2.   // debugImplementation because LeakCanary should only run in debug builds.
  3.   debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14'
  4. }
复制代码
不需要更改代码!需要是debug Build Variants 编译的APK即可。
LeakCanary 自动检测以下对象的泄漏:

当应用程序存在内存泄漏时,一样平常的源自我们频仍的一些利用,导致一些资源没有实时回收。当LeakCanary检测到内存泄漏时,会自动Capture heap dump,并且有关照提示,我们可以直接在手机上查看分析结果。
也可以通过 Logcat 过滤关键字 LeakCanary
  1. server@dev-fj-srv:$ adb logcat -s LeakCanary
  2. --------- beginning of main
  3. 07-19 17:53:33.279 17243 17261 D LeakCanary: LeakCanary is running and ready to detect memory leaks.
  4. 07-19 17:53:35.348 17243 17243 D LeakCanary: Watching instance of androidx.coordinatorlayout.widget.CoordinatorLayout (com.android.deskclock.stopwatch.StopwatchFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks)) with key ac040ec7-3aa5-479f-9713-f0d13d337cf1
  5. 07-19 17:53:36.306 17243 17243 D LeakCanary: Watching instance of android.widget.LinearLayout (com.android.deskclock.AlarmClockFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks)) with key 9108d714-d6bf-4f44-baf7-e24a256ecf98
  6. 07-19 17:53:36.326 17243 17243 D LeakCanary: Watching instance of androidx.coordinatorlayout.widget.CoordinatorLayout (com.android.deskclock.ClockFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks)) with key 706ac657-99b7-4938-94e9-84a5877dc58b
  7. 07-19 17:53:36.662 17243 17243 D LeakCanary: Watching instance of androidx.coordinatorlayout.widget.CoordinatorLayout (com.android.deskclock.stopwatch.StopwatchFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks)) with key f295fa5b-486f-407c-a352-0091c8bab6fc
  8. 07-19 17:53:36.802 17243 17243 D LeakCanary: Watching instance of com.android.deskclock.timer.TimerItem (com.android.deskclock.timer.TimerItemFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks)) with key ff32d891-06a9-4ec1-9e3d-6225aabb4edb
  9. 07-19 17:53:36.803 17243 17243 D LeakCanary: Watching instance of android.widget.FrameLayout (com.android.deskclock.timer.TimerFragment received Fragment#onDestroyView() callback (references to its views should be cleared to prevent leaks)) with key 464d6297-f4b7-4eaa-820c-f054e71c3827
复制代码
发生泄漏时的日志
  1. 07-15 11:04:29.838 31292 31384 D LeakCanary: 2 APPLICATION LEAKS
  2. 07-15 11:04:29.838 31292 31384 D LeakCanary:
  3. 07-15 11:04:29.838 31292 31384 D LeakCanary: References underlined with "~~~" are likely causes.
  4. 07-15 11:04:29.838 31292 31384 D LeakCanary: Learn more at https://squ.re/leaks.
  5. 07-15 11:04:29.838 31292 31384 D LeakCanary:
  6. 07-15 11:04:29.838 31292 31384 D LeakCanary: 295210 bytes retained by leaking objects
  7. 07-15 11:04:29.838 31292 31384 D LeakCanary: Signature: 23d55def87c64b7c2617db75bc4bd2fb6fa36103
  8. 07-15 11:04:29.838 31292 31384 D LeakCanary: ┬───
  9. 07-15 11:04:29.838 31292 31384 D LeakCanary: │ GC Root: Thread object
  10. 07-15 11:04:29.838 31292 31384 D LeakCanary: │
  11. 07-15 11:04:29.838 31292 31384 D LeakCanary: ├─ com.android.internal.os.BackgroundThread instance
  12. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    Leaking: NO (MessageQueue↓ is not leaking)
  13. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    Retaining 293.6 kB in 4729 objects
  14. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    Thread name: 'android.bg'
  15. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    ↓ HandlerThread.mLooper
  16. 07-15 11:04:29.838 31292 31384 D LeakCanary: ├─ android.os.Looper instance
  17. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    Leaking: NO (MessageQueue↓ is not leaking)
  18. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    ↓ Looper.mQueue
  19. 07-15 11:04:29.838 31292 31384 D LeakCanary: ├─ android.os.MessageQueue instance
  20. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    Leaking: NO (MessageQueue#mQuitting is false)
  21. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    HandlerThread: "android.bg"
  22. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    ↓ MessageQueue[0]
  23. 07-15 11:04:29.838 31292 31384 D LeakCanary: │                  ~~~
  24. 07-15 11:04:29.838 31292 31384 D LeakCanary: ├─ android.os.Message instance
  25. 07-15 11:04:29.838 31292 31384 D LeakCanary: │    Leaking: UNKNOWN
  26. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Retaining 295.3 kB in 4733 objects
  27. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Message.what = 0
  28. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Message.when = 422519759 (6418 ms before heap dump)
  29. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Message.obj = null
  30. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Message.callback = instance @322313336 of android.media.MediaScannerConnection$$ExternalSyntheticLambda0
  31. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Message.target = instance @319818712 of android.os.Handler
  32. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    ↓ Message.callback
  33. 07-15 11:04:29.839 31292 31384 D LeakCanary: │              ~~~~~~~~
  34. 07-15 11:04:29.839 31292 31384 D LeakCanary: ├─ android.media.MediaScannerConnection$$ExternalSyntheticLambda0 instance
  35. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Leaking: UNKNOWN
  36. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Retaining 295.2 kB in 4732 objects
  37. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    f$0 instance of com.xxx.filemanager.activity.FileExplorerActivity with mDestroyed = true
  38. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    ↓ MediaScannerConnection$$ExternalSyntheticLambda0.f$0
  39. 07-15 11:04:29.839 31292 31384 D LeakCanary: │                                                       ~~~
  40. 07-15 11:04:29.839 31292 31384 D LeakCanary: ╰→ com.xxx.filemanager.activity.FileExplorerActivity instance
  41. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     Leaking: YES (ObjectWatcher was watching this because com.xxx.filemanager.activity.FileExplorerActivity
  42. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     received Activity#onDestroy() callback and Activity#mDestroyed is true)
  43. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     Retaining 295.2 kB in 4730 objects
  44. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     key = 9bf6a560-07b5-4e49-9836-d585492293bc
  45. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     watchDurationMillis = 5248
  46. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     retainedDurationMillis = 247
  47. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     mApplication instance of com.xxx.filemanager.FMApplication
  48. 07-15 11:04:29.839 31292 31384 D LeakCanary: ​     mBase instance of android.app.ContextImpl
  49. 07-15 11:04:29.839 31292 31384 D LeakCanary:
  50. 07-15 11:04:29.839 31292 31384 D LeakCanary: 280683 bytes retained by leaking objects
  51. 07-15 11:04:29.839 31292 31384 D LeakCanary: Signature: 6f2f983de93277fc32f3e5da91ae6581b246e338
  52. 07-15 11:04:29.839 31292 31384 D LeakCanary: ┬───
  53. 07-15 11:04:29.839 31292 31384 D LeakCanary: │ GC Root: Thread object
  54. 07-15 11:04:29.839 31292 31384 D LeakCanary: │
  55. 07-15 11:04:29.839 31292 31384 D LeakCanary: ├─ com.android.internal.os.BackgroundThread instance
  56. 07-15 11:04:29.839 31292 31384 D LeakCanary: │    Leaking: UNKNOWN
  57. 07-15 11:04:29.840 31292 31384 D LeakCanary: │    Retaining 293.6 kB in 4729 objects
  58. 07-15 11:04:29.840 31292 31384 D LeakCanary: │    Thread name: 'android.bg'
  59. 07-15 11:04:29.840 31292 31384 D LeakCanary: │    ↓ BackgroundThread<Java Local>
  60. 07-15 11:04:29.840 31292 31384 D LeakCanary: │                      ~~~~~~~~~~~~
  61. 07-15 11:04:29.840 31292 31384 D LeakCanary: ╰→ com.xxx.filemanager.activity.FileExplorerActivity instance
  62. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     Leaking: YES (ObjectWatcher was watching this because com.freeme.filemanager.activity.FileExplorerActivity
  63. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     received Activity#onDestroy() callback and Activity#mDestroyed is true)
  64. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     Retaining 280.7 kB in 4592 objects
  65. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     key = c6233ed5-0480-4c73-8eb1-addd3d520b66
  66. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     watchDurationMillis = 6531
  67. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     retainedDurationMillis = 1531
  68. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     mApplication instance of com.freeme.filemanager.FMApplication
  69. 07-15 11:04:29.840 31292 31384 D LeakCanary: ​     mBase instance of android.app.ContextImpl
  70. 07-15 11:04:29.840 31292 31384 D LeakCanary: ====================================
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4