【问题标题】:out of memory on every other run, on Android在 Android 上,每次运行时内存不足
【发布时间】:2012-05-17 07:53:08
【问题描述】:

我的应用程序在第一次运行时运行良好,但如果我重新启动它会崩溃并让我强制关闭。在我按下强制关闭按钮后,我可以再次启动应用程序。如果我在按下后退按钮后尝试重新启动,我必须强制关闭。我让我每次尝试都运行它而不会出错。我认为 android 应该负责将内存返回给计算机,所以我们不必做那些家务:我确实有一个有点大的数组:

int  worldgrid= new int[640][480][3];

在我的构造函数中,我可能不得不缩短它。我确实做了第一次尝试。记录猫消息:

05-08 19:09:46.035:E/dalvikvm-heap(420):28 字节内存不足 分配。

05-08 19:09:46.195: I/dalvikvm(420): |组=“主”sCount=0 dsCount=0 s=N obj=0x4001d8e0 self=0xccb0 05-08 19:09:46.195: 我/dalvikvm(420):| sysTid=420 nice=0 sched=0/0 cgrp=default 句柄=-1345026008 05-08 19:09:46.205: I/dalvikvm(420): | schedstat=(52616400652 22917249866 1196)05-08 19:09:46.205: I/dalvikvm(420):在 java.lang.reflect.Array.createMultiArray(Native 方法) 05-08 19:09:46.205: I/dalvikvm(420): at java.lang.reflect.Array.newInstance(Array.java:444) 05-08 19:09:46.455: I/dalvikvm(420): 在 com.gravedigger.MainGamePanel.(MainGamePanel.java:215) 05-08 19:09:46.455: I/dalvikvm(420): 在 com.digger.DiggerActivity.onCreate(GravediggerActivity.java:116) 05-08 19:09:46.615: I/dalvikvm(420): 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 05-08 19:09:46.625: I/dalvikvm(420): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 05-08 19:09:46.765: I/dalvikvm(420): 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 05-08 19:09:46.765: I/dalvikvm(420): 在 android.app.ActivityThread.access$2300(ActivityThread.java:125) 05-08 19:09:46.775: I/dalvikvm(420): 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 05-08 19:09:46.775: I/dalvikvm(420): 在 android.os.Handler.dispatchMessage(Handler.java:99) 05-08 19:09:46.785: I/dalvikvm(420): 在 android.os.Looper.loop(Looper.java:123) 05-08 19:09:46.785: 我/dalvikvm(420):在 android.app.ActivityThread.main(ActivityThread.java:4627) 05-08 19:09:46.895: I/dalvikvm(420): 在 java.lang.reflect.Method.invokeNative(Native Method) 05-08 19:09:46.895: I/dalvikvm(420): 在 java.lang.reflect.Method.invoke(Method.java:521) 05-08 19:09:46.895: 我/dalvikvm(420):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 05-08 19:09:46.895: I/dalvikvm(420): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 05-08 19:09:46.905: I/dalvikvm(420): 在 dalvik.system.NativeStart.main(本机方法)05-08 19:09:47.038: E/dalvikvm(420):HeapWorker 被楔入:11152ms 在里面花费 Lcom/android/internal/os/BinderInternal$GcWatcher;.finalize()V 05-08 19:09:47.038: I/dalvikvm(420): DALVIK 线程: 05-08 19:09:47.045: I/dalvikvm(420): "main" prio=5 tid=1 VMWAIT

05-08 19:09:47.045: I/dalvikvm(420): |组=“主”sCount=1 dsCount=0 s=N obj=0x4001d8e0 self=0xccb0 05-08 19:09:47.045: 我/dalvikvm(420):| sysTid=420 nice=0 sched=0/0 cgrp=default 句柄=-1345026008 05-08 19:09:47.045: I/dalvikvm(420): | schedstat=(52980087202 23270903160 1219)05-08 19:09:47.045: I/dalvikvm(420):在 java.lang.reflect.Array.createMultiArray(Native 方法) 05-08 19:09:47.045: I/dalvikvm(420): at java.lang.reflect.Array.newInstance(Array.java:444) 05-08 19:09:47.045: I/dalvikvm(420): 在 com.digger.MainGamePanel.(MainGamePanel.java:215) 05-08 19:09:47.045: I/dalvikvm(420): 在 com.digger.DiggerActivity.onCreate(GravediggerActivity.java:116) 05-08 19:09:47.045: I/dalvikvm(420): 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 05-08 19:09:47.185: I/dalvikvm(420): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 05-08 19:09:47.185: I/dalvikvm(420): 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 05-08 19:09:47.195: I/dalvikvm(420): 在 android.app.ActivityThread.access$2300(ActivityThread.java:125) 05-08 19:09:47.195:我/dalvikvm(420):在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 05-08 19:09:47.195: I/dalvikvm(420): 在 android.os.Handler.dispatchMessage(Handler.java:99) 05-08 19:09:47.195:我/dalvikvm(420):在 android.os.Looper.loop(Looper.java:123) 05-08 19:09:47.195: 我/dalvikvm(420):在 android.app.ActivityThread.main(ActivityThread.java:4627) 05-08 19:09:47.195:我/dalvikvm(420):在 java.lang.reflect.Method.invokeNative(Native Method) 05-08 19:09:47.195:我/dalvikvm(420):在 java.lang.reflect.Method.invoke(Method.java:521) 05-08 19:09:47.195: 我/dalvikvm(420):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 05-08 19:09:47.195: I/dalvikvm(420): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 05-08 19:09:47.195:我/dalvikvm(420):在 dalvik.system.NativeStart.main(本机方法)05-08 19:09:47.195: I/dalvikvm(420):“活页夹线程 #2”prio=5 tid=6 NATIVE 05-08 19:09:47.195:我/dalvikvm(420):| group="main" sCount=1 dsCount=0 s=N obj=0x44f366b8 self=0x11d230 05-08 19:09:47.195: I/dalvikvm(420): | sysTid=425 nice=0 sched=0/0 cgrp=默认句柄=1297528 05-08 19:09:47.195:我/dalvikvm(420):| schedstat=( 118912719 416670422 51 ) 05-08 19:09:47.195: I/dalvikvm(420): 在 dalvik.system.NativeStart.run(本机方法)05-08 19:09:47.195: I/dalvikvm(420):“活页夹线程 #1”prio=5 tid=5 NATIVE 05-08 19:09:47.195:我/dalvikvm(420):| group="main" sCount=1 dsCount=0 s=N obj=0x44f36480 self=0x11fd80 05-08 19:09:47.750: I/dalvikvm(420): | sysTid=424 nice=0 sched=0/0 cgrp=默认句柄=1269616 05-08 19:09:47.750:我/dalvikvm(420):| schedstat=( 114332827 305656917 35 ) 05-08 19:09:47.750: I/dalvikvm(420): 在 dalvik.system.NativeStart.run(本机方法)05-08 19:09:47.755: I/dalvikvm(420):“JDWP”守护进程prio=5 tid=4 VMWAIT 05-08 19:09:47.755: 我/dalvikvm(420):| group="系统" sCount=1 dsCount=0 s=N obj=0x44f352a0 self=0x135ad0 05-08 19:09:47.755: I/dalvikvm(420): | sysTid=423 nice=0 sched=0/0 cgrp=默认句柄=1196352 05-08 19:09:47.765:我/dalvikvm(420):| schedstat=( 59551849 158373474 18 ) 05-08 19:09:47.765: I/dalvikvm(420): 在 dalvik.system.NativeStart.run(本机方法)05-08 19:09:47.775: I/dalvikvm(420):“信号捕手”守护进程 prio=5 tid=3 VMWAIT 05-08 19:09:47.886:我/dalvikvm(420):| group="系统" sCount=1 dsCount=0 s=N obj=0x44f351e8 self=0x125550 05-08 19:09:47.886: I/dalvikvm(420): | sysTid=422 nice=0 sched=0/0 cgrp=默认句柄=1240608 05-08 19:09:47.886:我/dalvikvm(420):| schedstat=( 2639901 40055709 3 ) 05-08 19:09:47.886: I/dalvikvm(420): 在 dalvik.system.NativeStart.run(本机方法)05-08 19:09:47.886: I/dalvikvm(420):“HeapWorker”守护进程prio=5 tid=2 RUNNABLE 05-08 19:09:47.886:我/dalvikvm(420):| group="系统" sCount=0 dsCount=0 s=N obj=0x438b8e50 self=0x12ece0 05-08 19:09:47.886: I/dalvikvm(420): | sysTid=421 nice=0 sched=0/0 cgrp=默认句柄=1195896 05-08 19:09:47.906:我/dalvikvm(420):| schedstat=( 4477669539 2785983510 211) 05-08 19:09:47.906: I/dalvikvm(420): 在 com.android.internal.os.BinderInternal$GcWatcher.finalize(BinderInternal.java:~48) 05-08 19:09:47.906: I/dalvikvm(420): 在 dalvik.system.NativeStart.run(本机方法)05-08 19:09:47.906: D/dalvikvm(420): threadid=2: 发送两个 SIGSTKFLTs 到 threadid=2 (tid=421) 导致调试器转储 05-08 19:09:57.895: D/dalvikvm(420): 发送,暂停让调试器运行 05-08 19:10:05.956: D/dalvikvm(420): 继续 05-08 19:10:05.956: E/dalvikvm(420): VM 中止

【问题讨论】:

    标签: android memory


    【解决方案1】:

    可能,在内存中拥有如此大的数组并不好。 但无论如何,您可以通过以下方式重构数组来减少内存使用量: int worldgrid = new int[3][480][640];

    这个技巧会多次减少内存使用。它与数组和每个项目的 java 内存开销有关,详细信息可以在这里找到。 http://www.javamex.com/tutorials/memory/array_memory_usage.shtml

    还要检查,您没有保留任何指向数组的链接,这会阻止将其从内存中删除。此外,垃圾收集器不会在删除所有链接后立即从内存中删除。因此,如果您不使指向等于 null 的数组的链接,它会保存在内存中,并且当您重新启动应用程序时(无法保证活动被完全杀死),并尝试在 onCreate 中创建数组(正如我从日志中看到的那样) 旧数组还不能删除。

    【讨论】:

      【解决方案2】:

      我无法告诉您为什么您每次都收到错误而没有看到您的其余代码。你有正在使用的静态变量吗?

      但是,我可以建议您将内存消耗减少 3 倍。看起来您正在尝试存储 rgb 图像。问题是每个红色、绿色或蓝色像素只需要一个字节,但你给它一个 int 是 4 个字节。更好的方法是将红色、绿色和蓝色编码为单个 int,使用:int color = Color.rgb(red, geen, blue)这样您只需将数组初始化为int[] worldgrid= new int[640][480],并将内存使用量减少 3 倍。

      此外,您甚至可能根本不应该将其存储为多维数组,只需执行int[] worldgrid = new int[640*480];,在索引到数组时,只需执行:int result = worldgrid[row + col*640];

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 2022-12-10
        • 1970-01-01
        • 2020-02-06
        相关资源
        最近更新 更多