hoo*_*d82 1 android memory-management out-of-memory
我正在检查我的应用程序内存泄漏/使用情况,并且遇到了一些奇怪的东西,到目前为止我在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
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,没有任何东西被解除分配/ GC,活动堆积,AppContexts等等,直到应用程序崩溃与OutOfMemoryError.这不会发生在2.2+上.
有人能告诉我为什么会这样吗?我有一种感觉它或者是简单的东西,或者它只是我的应用程序的奇怪东西,但我不知道为什么会发生这种情况.
仅供参考,我在1.6和2.1仿真器中以及我的G1运行1.6中重现了这一点.用户最近的崩溃报告也显示了这一点,他们在Droid Eris上运行2.1.如果需要更多细节/代码来帮助我,请告诉我.
## UPDATE ##
感谢momo的信息,我能够找到一些内存泄漏问题,这大大减少了将在meminfo的Objects列表中显示的Activities/AppContexts的数量.
现在这个数字已经下降到了我的应用程序中的实际活动数量,因此在旧版本的Android上,它会显示应用程序正在消耗的对象总数.在较新的版本上它不会,但这可能只是我的测试设备上的情况.
为了清楚地了解为什么要保持活动,我通常使用MAT,然后从被卡住的Activity中查看GC根路径.
我创建了一个简单的项目,它加载简单的TestActivity以说明该过程.以下是它的代码:
package com.so;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是步骤:


您应该看到您的Activity由com.android.internal.policy.impl.PhoneWindow $ DecorView保留,而不是其他人.如果是这种情况,您就可以了,GC最终将回收此活动.
现在我将更改我的类以包含一个将保存其自己的实例的静态变量:
package com.so;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
public class TestActivity extends Activity {
static ArrayList memoryLeakList;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// create a deliberate static list to cause the leak
TestActivity.memoryLeakList = new ArrayList();
TestActivity.memoryLeakList.add(this);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我用相同的步骤运行代码hprof,我现在得到的活动的引用由ArrayList保存,而不是com.android.internal.policy.impl.PhoneWindow $ DecorView表示有可能发生泄漏我不清理阵列

现在,您不必为每个Activity执行此操作,我只需简单地运行应用程序然后转储HPROF.然后,您将再次按包筛选以获取应用程序的快照.在初始直方图中,在DDMS中点击GC按钮并从那里开始调查后,您应该怀疑任何具有多个实例的活动.
还有一点需要注意,在我的2.1手机上,我无法通过DDMS获得HPROF,所以我按照以下步骤通过模拟器完成了:
由于hprof是基于dalvik的,为了将其与内存分析工具一起使用,您需要首先通过Android SDK安装的tools目录中的hprof-conv进行转换.
Run ./hprof-conv [source dump] [target dump]