Android 内存使用情况以及内存中的对象在 1.6 和 2.1 中未释放
我正在检查我的应用程序的内存泄漏/使用情况,发现了一些奇怪的东西,到目前为止我只在 Android 1.6 和 2.1 中看到过。在应用程序中单击一下并为我的应用程序运行“adb shell dumpsys meminfo”后,我看到以下内容:
DUMP OF SERVICE meminfo:
Applications Memory Usage (kB):
Uptime: 34639912 Realtime: 153524709
** MEMINFO in pid 5778 [com.app.myapp] **
native dalvik other total
size: 14336 4679 N/A 19015
allocated: 13971 4139 N/A 18110
free: 280 540 N/A 820
(Pss): 2986 4181 13491 20658
(shared dirty): 972 3948 620 5540
(priv dirty): 2876 3224 10976 17076
Objects
Views: 545 ViewRoots: 4
AppContexts: 32 Activities: 31
Assets: 2 AssetManagers: 2
Local Binders: 43 Proxy Binders: 79
Death Recipients: 2
OpenSSL Sockets: 1
SQL
heap: 91 dbFiles: 0
numPagers: 4 inactivePageKB: 0
activePageKB: 0
Asset Allocations
zip:/data/app/com.app.myapp.apk:/resources.arsc: 119K
如您所见,没有任何内容被释放/GC,活动正在堆积,AppContexts等直到应用程序因 OutOfMemoryError 崩溃。这在 2.2+ 上不会发生。
谁能给我一些关于为什么会发生这种情况的见解?我有一种感觉,这要么是简单的事情,要么就是我的应用程序有些奇怪,但我不知道为什么会发生这种情况。
仅供参考,我在 1.6 和 2.1 模拟器以及运行 1.6 的 G1 中重现了这一点。一位用户最近的崩溃报告也显示了这一点,他们在 Droid Eris 上运行 2.1。如果需要更多详细信息/代码来帮助解决此问题,请告诉我。
##UPDATE##
感谢 momo 提供的信息,我能够找到一些内存泄漏问题,这大大减少了 meminfo 对象列表中显示的 Activity/AppContext 数量。
该数字现在已降至我的应用程序中实际活动的数量左右,因此似乎在旧版本的 Android 上,它将显示您的应用程序正在消耗的对象总量。在较新的版本上不会,尽管这可能只是我的测试设备上的情况。
I'm checking my app for Memory Leaks/Usage and came across something weird that I've only seen so far in Android 1.6 and 2.1. After clicking around in the app a bit and I run "adb shell dumpsys meminfo" for my application, I see the following:
DUMP OF SERVICE meminfo:
Applications Memory Usage (kB):
Uptime: 34639912 Realtime: 153524709
** MEMINFO in pid 5778 [com.app.myapp] **
native dalvik other total
size: 14336 4679 N/A 19015
allocated: 13971 4139 N/A 18110
free: 280 540 N/A 820
(Pss): 2986 4181 13491 20658
(shared dirty): 972 3948 620 5540
(priv dirty): 2876 3224 10976 17076
Objects
Views: 545 ViewRoots: 4
AppContexts: 32 Activities: 31
Assets: 2 AssetManagers: 2
Local Binders: 43 Proxy Binders: 79
Death Recipients: 2
OpenSSL Sockets: 1
SQL
heap: 91 dbFiles: 0
numPagers: 4 inactivePageKB: 0
activePageKB: 0
Asset Allocations
zip:/data/app/com.app.myapp.apk:/resources.arsc: 119K
As you can see, nothing is getting deallocated/GC'd, the Activities are piling up, the AppContexts, etc. until the app just crashes with an OutOfMemoryError. This doesn't happen on 2.2+.
Can anybody give me some insight into why this is happening? I have a feeling it's either something simple, or it's just something weird with my app, but I'm at a loss as to why this is happening.
FYI, I've reproduced this in a 1.6 and 2.1 emulator, as well as my G1 running 1.6. A recent crash report from a user also shows this, which they were running 2.1 on a Droid Eris. Let me know if any more details/code is needed to help with this.
##UPDATE##
Thanks to the info from momo, I was able to track down some memory leak issues, which drastically cut down on the amount of Activities/AppContexts that would show in the Objects list of meminfo.
The number is now down to around the number of actual activities that are in my application, so it seems that on older versions of Android, it will show the total amount of objects your app is consuming. On newer versions it won't, though that could just be only the case on my test devices.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了清楚地了解 Activity 被阻止的原因,我通常使用 MAT,然后查看卡住的 Activity 到 GC 根的路径。
我创建了一个简单的项目,它加载简单的 TestActivity 以说明该过程。下面是它的代码:
步骤如下:
您应该看到您的活动是由 com.android.internal.policy.impl.PhoneWindow$DecorView 持有,没有其他人持有。如果是这种情况,没关系,这个 Activity 最终会被 GC 回收。
现在我将更改我的类以包含一个将保存其自己的实例的静态变量:
如果我使用相同的步骤运行代码 hprof,我现在得到的 Activity 的引用由 ArrayList 而不是 com.android 保存.internal.policy.impl.PhoneWindow$DecorView 表示如果我不清理数组,就有可能发生泄漏
现在,您不必对每个 Activity 都这样做,我要做的只是简单地运行应用程序,然后转储 HPROF。然后,您将再次按包进行过滤以获取应用程序的快照。在初始直方图中,您应该对在 DDMS 中点击 GC 按钮后实例数量超过 1 的任何活动表示怀疑,并从那里开始调查。
还要注意的是,在我的 2.1 手机上,我无法通过 DDMS 获取 HPROF,因此我按照以下步骤通过模拟器进行操作:
由于 hprof 是基于 dalvik 的,为了将其与内存分析工具一起使用,您需要需要首先通过工具中提供的 hprof-conv 进行转换Android SDK 安装目录
To get a clear picture on why Activities are held up, I normally use MAT and then look at Path to GC root from the Activity that get stuck.
I've a created a simple project which load simple TestActivity in order to illustrate the process. Below is the code for it:
Here are the steps:
You should see that your Activity is held by com.android.internal.policy.impl.PhoneWindow$DecorView and no one else. If this is the a case, you are ok and this Activity will be eventually reclaimed by GC.
Now I will do change my class to include a static variable that will hold its own instance:
And if I run the code hprof with the same steps, I now get the reference of the Activity is held by the ArrayList and not the com.android.internal.policy.impl.PhoneWindow$DecorView signifying that there is possibility of a leak if I don't clean up the array
Now, you don't have to do that for every Activity, what I would do just briefly run the app and then dump the HPROF. You would then again filter by package to get the snapshot of your application. In the initial Histogram, you should be suspicious for any Activity that has number of instances more than one after hitting GC button in DDMS and start investigating from there.
One more note, on my 2.1 phones, I couldn't get the HPROF via DDMS, so I did it through the emulator following these steps:
Since the hprof is dalvik based, in order to use it with memory profiling tools you need to convert it first via hprof-conv available in the tools directory of your Android SDK installation
使用内存分析器 (MAT) 查看您的进程堆。
http://www.eclipse.org/mat/
Use Memory Analyzer (MAT) to view your process Heap.
http://www.eclipse.org/mat/