不同设备中的Android OutOfMemory?

不同设备中的Android OutOfMemory?,android,bitmap,logcat,Android,Bitmap,Logcat,我有一个处理图像的应用程序,它适用于一些设备,比如HTC ONE X,而其他设备则不适用。GALAXY NOTE,这个列表很难回答这个问题,因为它在一些设备上有效,而在其他设备上无效。而且它在模拟器上不起作用——默认的,但在一个小的模拟器上起作用 这是我得到的logcat 08-15 18:30:39.070: I/dalvikvm-heap(334): Clamp target GC heap from 25.723MB to 24.000MB 08-15 18:30:39.090: D/da

我有一个处理图像的应用程序,它适用于一些设备,比如HTC ONE X,而其他设备则不适用。GALAXY NOTE,这个列表很难回答这个问题,因为它在一些设备上有效,而在其他设备上无效。而且它在模拟器上不起作用——默认的,但在一个小的模拟器上起作用

这是我得到的logcat

08-15 18:30:39.070: I/dalvikvm-heap(334): Clamp target GC heap from 25.723MB to 24.000MB
08-15 18:30:39.090: D/dalvikvm(334): GC_FOR_MALLOC freed <1K, 51% free 2672K/5379K, external 19015K/19657K, paused 38ms
08-15 18:30:39.370: D/dalvikvm(334): GC_EXTERNAL_ALLOC freed <1K, 51% free 2672K/5379K, external 19015K/19657K, paused 45ms
08-15 18:30:39.400: E/dalvikvm-heap(334): 810000-byte external allocation too large for this process.
08-15 18:30:39.510: I/dalvikvm-heap(334): Clamp target GC heap from 25.724MB to 24.000MB
08-15 18:30:39.510: E/GraphicsJNI(334): VM won't let us allocate 810000 bytes
08-15 18:30:39.510: D/dalvikvm(334): GC_FOR_MALLOC freed 0K, 51% free 2672K/5379K, external 19015K/19657K, paused 36ms
08-15 18:30:39.532: D/AndroidRuntime(334): Shutting down VM
08-15 18:30:39.532: W/dalvikvm(334): threadid=1: thread exiting with uncaught exception (group=0x40015560)
08-15 18:30:39.600: E/AndroidRuntime(334): FATAL EXCEPTION: main
08-15 18:30:39.600: E/AndroidRuntime(334): java.lang.RuntimeException: Unable to start activity ComponentInfo{app.com.android.editor/app.com.android.editor.Option}: android.view.InflateException: Binary XML file line #317: Error inflating class <unknown>
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.os.Handler.dispatchMessage(Handler.java:99)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.os.Looper.loop(Looper.java:123)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.ActivityThread.main(ActivityThread.java:3683)
08-15 18:30:39.600: E/AndroidRuntime(334):  at java.lang.reflect.Method.invokeNative(Native Method)
08-15 18:30:39.600: E/AndroidRuntime(334):  at java.lang.reflect.Method.invoke(Method.java:507)
08-15 18:30:39.600: E/AndroidRuntime(334):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-15 18:30:39.600: E/AndroidRuntime(334):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-15 18:30:39.600: E/AndroidRuntime(334):  at dalvik.system.NativeStart.main(Native Method)
08-15 18:30:39.600: E/AndroidRuntime(334): Caused by: android.view.InflateException: Binary XML file line #317: Error inflating class <unknown>
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.createView(LayoutInflater.java:518)
08-15 18:30:39.600: E/AndroidRuntime(334):  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
08-15 18:30:39.600: E/AndroidRuntime(334):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.Activity.setContentView(Activity.java:1657)
08-15 18:30:39.600: E/AndroidRuntime(334):  at app.com.android.editor.Option.onCreate(Option.java:40)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-15 18:30:39.600: E/AndroidRuntime(334):  ... 11 more
08-15 18:30:39.600: E/AndroidRuntime(334): Caused by: java.lang.reflect.InvocationTargetException
08-15 18:30:39.600: E/AndroidRuntime(334):  at java.lang.reflect.Constructor.constructNative(Native Method)
08-15 18:30:39.600: E/AndroidRuntime(334):  at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.LayoutInflater.createView(LayoutInflater.java:505)
08-15 18:30:39.600: E/AndroidRuntime(334):  ... 25 more
08-15 18:30:39.600: E/AndroidRuntime(334): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.Bitmap.nativeCreate(Native Method)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.Bitmap.createBitmap(Bitmap.java:477)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.Bitmap.createBitmap(Bitmap.java:444)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:498)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:473)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.content.res.Resources.loadDrawable(Resources.java:1709)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.view.View.<init>(View.java:1951)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.widget.TextView.<init>(TextView.java:344)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.widget.Button.<init>(Button.java:108)
08-15 18:30:39.600: E/AndroidRuntime(334):  at android.widget.Button.<init>(Button.java:104)
08-15 18:30:39.600: E/AndroidRuntime(334):  ... 28 more
08-15 18:30:45.459: I/Process(334): Sending signal. PID: 334 SIG: 9
08-15 18:30:39.070:I/dalvikvm堆(334):将目标GC堆从25.723MB钳制到24.000MB

08-15 18:30:39.090:D/dalvikvm(334):用于释放MALLOC的GC\u堆大小因设备而异。在应用具有较大堆大小的设备上,您遇到的问题比在应用具有较小堆大小的设备上遇到的问题要少,这是完全合理的。如果您支持较旧/分辨率较低的设备,您的堆可能会低至16MB。

大多数android的空间有限。通常为16MB。我强烈建议看一下你的图片大小。还可以使用弱引用,以确保图像仅在访问时使用内存。(弱引用将强制收集的垃圾更快地清理它们。)

  • 我不太了解你的应用程序,只知道你的logcat错误列表,但是如果你有多个活动,就把那些你不需要的活动杀掉。这似乎是显而易见的建议,也许不是,但它会释放空间
这句话说明了一切。 位图占用了某些设备(VM堆栈限制更高的设备)的所有内存。您应该研究此应用程序的更好的内存管理,例如LruCache、解码质量较低的位图等

编辑: 不要像某些用户建议的那样使用WeakReference。 检查此问题和此视频


直接向平台创建者解释/教导/技术,并说不要使用WeakReference。

正如其他人所说,应用程序的堆大小是有限的。最小值为16MB,可在设备之间验证(这是虚拟机的一种设置)

您可以做的一些建议:

  • 如果不需要全分辨率,可以加载较小版本的图像。以下是如何做到这一点:
  • 检查是否有足够的可用内存;如果内存不足,您可以立即释放不直接需要的图像,并在需要时再次加载它们
  • 下面是一些用于检查剩余可用内存量的代码:

    long free = Runtime.getRuntime().freeMemory();
    

    很好的建议。这里有更多关于。一句话:如果你的手机没有足够的内存再分配800K,那么它就是没有足够的内存。不管怎样,它迟早会失败的。您只需要加载更少、更小的图像:)谢谢您的投票!事实上,两周前我也遇到过同样的问题,当我使用弱引用时,它极大地帮助了我的程序!我唯一要避免的是(当我有这个问题的时候,我读了很多关于这个问题的观点。它们是混合的。)通过类似System.gc()的东西直接调用垃圾收集器。“一般来说,在存在垃圾收集器的情况下,手动调用GC从来都不是一个好的做法。GC是围绕启发式算法组织的,当留给它们自己的设备时,启发式算法工作得最好。手动调用GC通常会降低性能。”(多亏了stackoverflow上的Thomas Pornin,他给出了一个措辞巧妙的回答。我总是引用他对gc Usage的回应,因为它的措辞太好了。)差点忘了!如果你想检查什么占用了空间以及占用了多少空间,请安装eclipse内存分析器工具(MAT)对于android应用程序。关于如何设置和使用它,在线上有非常简单的说明。在为android编程时非常有用!我支持这一点,而且我使用的是Fedor的解码器。为什么它仍然存在?我还应该用些什么?@AhmedAl ekrii:“我正在使用Fedor的解码器”--我肯定Fedor很欣赏这一点,但我不知道你在说什么。“为什么它还在那儿?”--如果“它在”是您的
    OutOfMemoryError
    ,这是因为您没有足够的堆空间来分配此
    位图
    。这可能是因为您通常没有足够的空间,或者没有足够大的连续内存块(例如,您想要800KB,您有2MB的堆可用,但没有单个800+KB的块)谢谢,我通过循环利用得到了更多的堆空间,对吗?你推荐弱引用吗?因为有些是,有些不是t@AhmedAl-ekrii:调用
    recycle()
    在您的
    位图上
    对象使用完毕后,将比垃圾收集更快地释放它们的内存。
    SoftReference
    WeakReference
    不推荐使用,如文档中所示:
    long free = Runtime.getRuntime().freeMemory();