【发布时间】:2014-06-19 07:52:29
【问题描述】:
我真的不知道如何处理这种情况。突然之间,我在特定 Activity 上收到 OutOfMemoryException ,并且每次在我正在开发的游戏中遵循相同的路径时,它都是相同的。我在我的游戏中使用了很多 Drawable。我在某处读到您应该经常执行 Bitmap.recycle() 以释放内存。但我几乎从不直接使用 Bitmaps,而我使用的 Drawabels,我需要它们出现在屏幕上。
我使用 Facebook 和 Parse SDK 可能没有帮助。
现在我正在手机和模拟器上进行开发。在模拟器中,堆大小不能超过 30 MB。我应该增加这个数字还是应该不理会并尽量减少我的应用程序的内存消耗?
直到最近,我一直认为,一旦我完成一个 Activity 并进入另一个 Activity,一切都会被垃圾回收,我会重新开始 示例代码:
private void startGamesActivity() {
Intent intent = new Intent(this, SS3GamesActivity.class);
startActivity(intent);
finish();
}
这不是真的吗? 让我进一步详细说明。我有一个包含两个可能的 Facebook 播放器的 ListView 的活动。当我单击其中一个以启动一项新活动时会发生 OutOfMemoryException,该活动应该比以前消耗更少的内存!这就是为什么我不明白为什么 OutOfMemoryException 甚至会发生!两个 ListView 被垃圾回收后应该还有足够的内存!
所以我现在要做的是分析我的堆消耗。我还下载了 Eclipse 内存分析器。正在使用的最大内存块是 1 字节数组(byte[], boolean[]),计数为 702,总大小为 20,096 MB,其中最大为 6,240 MB,平均为 29,314 MB。这让我很震惊!它甚至不会在整个应用程序中增加很多。但是在模拟器中看到堆大小不会增加超过 30MB,因为有很大的潜力。
使用 Eclipse 内存分析器还给了我两个可能的内存泄漏罪魁祸首。
问题嫌疑人 1 “”加载的“android.graphics.Bitmap”的一个实例占用 6.543.416 (28,00%) 个字节。内存是在 "" 加载的 "byte[]" 的一个实例中累积的。
问题嫌疑人 2 由“”加载的“android.content.res.Resources”类占用5.212.968(22,31%)字节。内存在“”加载的“java.lang.Object[]”的一个实例中累积。
结果并不像我想象的那么简单。我认为从类名来看可能的嫌疑人是我的 LruCache。我使用它来填充可能的玩家照片的 Facebook 缩略图,以便每次用户在 ListView 中滚动时都不会从网络加载它们。我不确定为什么它在我的应用程序开始时就已经这么大了。我已经尝试过让它更小,但没有运气。
这是在我的 MainActivity 的 onCreate 中:
// caching system
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 16; // used to be 8, didnt help though
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
我还检查了第二个可能的嫌疑人,即资源,我真的无能为力。似乎有我正在使用的所有布局对象,而且我现在正在做的事情不能少用。
在我们这样做的时候,“onDestroy”之类的东西会有所帮助吗?
public class ExampleActivity extends Activity {
HashMap<String, String> meMap=new HashMap<String, String>();
static ArrayList<String> meArray = new ArrayList<String>();
protected void onDestroy() {
super.onDestroy();
meMap.clear();
meMap = null;
meArray.clear();
meArray = null;
}
}
因为我没有看到内存消耗有太大差异,所以我认为 gc 会自动执行此操作。
对于我的问题,我很乐意接受所有可能的建议。我什至可以提供更多信息,但目前我什至不知道是什么。
绿色的 StackTrace:
05-06 07:37:12.373: I/dalvikvm(529): Wrote stack traces to '/data/anr/traces.txt'
05-06 07:37:12.523: E/dalvikvm-heap(529): Out of memory on a 3601936-byte allocation.
05-06 07:37:12.523: I/dalvikvm(529): "main" prio=5 tid=1 RUNNABLE
05-06 07:37:12.533: I/dalvikvm(529): | group="main" sCount=0 dsCount=0 obj=0x409c1460 self=0x12810
05-06 07:37:12.533: I/dalvikvm(529): | sysTid=529 nice=0 sched=0/0 cgrp=default handle=1074082952
05-06 07:37:12.533: I/dalvikvm(529): | schedstat=( 8842421920 6327029011 3892 ) utm=778 stm=106 core=0
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.Bitmap.nativeCreate(Native Method)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
05-06 07:37:12.533: I/dalvikvm(529): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
05-06 07:37:12.533: I/dalvikvm(529): at android.content.res.Resources.loadDrawable(Resources.java:1935)
05-06 07:37:12.533: I/dalvikvm(529): at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
05-06 07:37:12.533: I/dalvikvm(529): at android.widget.ImageView.<init>(ImageView.java:119)
05-06 07:37:12.533: I/dalvikvm(529): at android.widget.ImageView.<init>(ImageView.java:109)
05-06 07:37:12.533: I/dalvikvm(529): at java.lang.reflect.Constructor.constructNative(Native Method)
05-06 07:37:12.533: I/dalvikvm(529): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
05-06 07:37:12.533: I/dalvikvm(529): at android.view.LayoutInflater.createView(LayoutInflater.java:586)
05-06 07:37:12.533: I/dalvikvm(529): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
05-06 07:37:12.533: I/dalvikvm(529): at android.view.LayoutInflater.onCreateView(LayoutInflater.java:653)
05-06 07:37:12.543: I/dalvikvm(529): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:678)
05-06 07:37:12.543: I/dalvikvm(529): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
05-06 07:37:12.543: I/dalvikvm(529): at android.view.LayoutInflater.rInflate(LayoutInflater.java:742)
05-06 07:37:12.543: I/dalvikvm(529): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
05-06 07:37:12.543: I/dalvikvm(529): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
05-06 07:37:12.543: I/dalvikvm(529): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
05-06 07:37:12.543: I/dalvikvm(529): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:251)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.Activity.setContentView(Activity.java:1835)
05-06 07:37:12.543: I/dalvikvm(529): at com.quizdom.SS7ChooseTopicsActivity.onCreate(SS7ChooseTopicsActivity.java:36)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.Activity.performCreate(Activity.java:4465)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.ActivityThread.access$600(ActivityThread.java:123)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
05-06 07:37:12.543: I/dalvikvm(529): at android.os.Handler.dispatchMessage(Handler.java:99)
05-06 07:37:12.543: I/dalvikvm(529): at android.os.Looper.loop(Looper.java:137)
05-06 07:37:12.543: I/dalvikvm(529): at android.app.ActivityThread.main(ActivityThread.java:4424)
05-06 07:37:12.543: I/dalvikvm(529): at java.lang.reflect.Method.invokeNative(Native Method)
05-06 07:37:12.543: I/dalvikvm(529): at java.lang.reflect.Method.invoke(Method.java:511)
05-06 07:37:12.543: I/dalvikvm(529): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-06 07:37:12.543: I/dalvikvm(529): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-06 07:37:12.543: I/dalvikvm(529): at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
-
您是否尝试过清单中的 Large heap size = true。 xml
-
是的,对模拟器没有影响
-
也许您的布局正遭受过度绘制的困扰?如果是这样,您的布局使用的内存比必要的多。在此处阅读有关透支的信息:udinic.wordpress.com/tag/overdraw