Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:库中内存不足异常_Android_Memory Leaks_Gallery - Fatal编程技术网

Android:库中内存不足异常

Android:库中内存不足异常,android,memory-leaks,gallery,Android,Memory Leaks,Gallery,我的应用程序显示了9个类别的列表,每个类别都显示了Neil Davies慷慨提供的基于图库的coverflow,以及所选类别的图像 这些图像是从网络上获取的,每个图像的大小从300K到500K不等,并存储在一个可绘制的数组列表中。此数据使用下面的BaseAdapter代码绑定到coverflow。 每次我退出coverflow并返回类别列表时,我都会再次清除arrayList,代码如下 在场景1中,我的arrayList包含5个可提取项。在这个场景中,我可以自由浏览所有类别并显示它们的图像。在我

我的应用程序显示了9个类别的列表,每个类别都显示了Neil Davies慷慨提供的基于图库的coverflow,以及所选类别的图像

这些图像是从网络上获取的,每个图像的大小从300K到500K不等,并存储在一个可绘制的数组列表中。此数据使用下面的BaseAdapter代码绑定到coverflow。 每次我退出coverflow并返回类别列表时,我都会再次清除arrayList,代码如下

在场景1中,我的arrayList包含5个可提取项。在这个场景中,我可以自由浏览所有类别并显示它们的图像。在我的测试中,我在所有类别中循环了5次,这似乎足以确定没有问题

在场景2中,我的arrayList包含10个可提取项。在这种情况下,我在浏览第5或第6类中的图像时会出现OutOfMemoryError异常:

07-13 08:38:21.266: ERROR/dalvikvm-heap(2133): 819840-byte external allocation too large for this process. 07-13 08:38:21.266: ERROR/(2133): VM won't let us allocate 819840 bytes 07-13 08:38:21.277: DEBUG/skia(2133): --- decoder->decode returned false 07-13 08:38:21.287: WARN/dalvikvm(2133): threadid=25: thread exiting with uncaught exception (group=0x4001b188) 07-13 08:38:21.296: ERROR/AndroidRuntime(2133): Uncaught handler: thread Thread-64 exiting due to uncaught exception 07-13 08:38:21.308: ERROR/AndroidRuntime(2133): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 07-13 08:38:21.308: ERROR/AndroidRuntime(2133): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 07-13 08:38:21.308: ERROR/AndroidRuntime(2133): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459) 07-13 08:38:21.308: ERROR/AndroidRuntime(2133): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 07-13 08:38:21.308: ERROR/AndroidRuntime(2133): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 07-13 08:38:21.308: ERROR/AndroidRuntime(2133): at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657) 在输入类别时填充数据源:

for (int i = 0; i < ImageBuffer.getInstance().getImageArraySize(); i++)  
{  
  String imageUrl = ImageBuffer.getInstance().getImageUrl(i);  
  Log.v("Initial", imageUrl);  
  Drawable fullImage = AsyncImageLoader.getInstance().loadImageByUrl(imageUrl);  
  ImageBuffer.getInstance().getImages().add(i, fullImage);  

}
在finish中退出类别时清除数据源:

for (int i = 0; i < ImageBuffer.getInstance().getImageArraySize(); i++)  
{  
  if (ImageBuffer.getInstance().images.get(i) != null)  
            {  
                ImageBuffer.getInstance().images.get(i).setCallback(null);  
                ImageBuffer.getInstance().images.set(i, null);  
            }    

}
编辑:

好的,我在coverflow上应用了Mathias的LogHeap函数,下面是一些输出。 在加载第一个库之前:

DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 6.20MB of 6.28MB (0.07MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (0.00MB free) DEBUG/dalvikvm(5221): GC freed 4558 objects / 638152 bytes in 84ms DEBUG/dalvikvm(5221): GC freed 17 objects / 808 bytes in 67ms DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 14.83MB of 16.89MB (0.11MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 330 objects / 17920 bytes in 77ms DEBUG/dalvikvm(5221): GC freed 13 objects / 760 bytes in 67ms 进入第一个画廊后:

DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 14.90MB of 16.89MB (0.07MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 357 objects / 50080 bytes in 68ms DEBUG/dalvikvm(5221): GC freed 353 objects / 27312 bytes in 67ms 在现有第一个库之后:

DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 6.20MB of 6.28MB (0.07MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (0.00MB free) DEBUG/dalvikvm(5221): GC freed 4558 objects / 638152 bytes in 84ms DEBUG/dalvikvm(5221): GC freed 17 objects / 808 bytes in 67ms DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 14.83MB of 16.89MB (0.11MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 330 objects / 17920 bytes in 77ms DEBUG/dalvikvm(5221): GC freed 13 objects / 760 bytes in 67ms 进入第五画廊后:

DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 16.80MB of 23.32MB (0.08MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 842 objects / 99256 bytes in 73ms DEBUG/dalvikvm(5221): GC freed 306 objects / 24896 bytes in 69ms DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 16.74MB of 23.32MB (0.11MB free) in [com.example.Coverlow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 331 objects / 18184 bytes in 68ms DEBUG/dalvikvm(5221): GC freed 60 objects / 3128 bytes in 68ms 退出第五画廊后:

DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 16.80MB of 23.32MB (0.08MB free) in [com.example.Coverflow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 842 objects / 99256 bytes in 73ms DEBUG/dalvikvm(5221): GC freed 306 objects / 24896 bytes in 69ms DEBUG/Application(5221): debug. ================================= DEBUG/Application(5221): debug.heap native: allocated 16.74MB of 23.32MB (0.11MB free) in [com.example.Coverlow] DEBUG/Application(5221): debug.memory: allocated: 4.00MB of 24.00MB (1.00MB free) DEBUG/dalvikvm(5221): GC freed 331 objects / 18184 bytes in 68ms DEBUG/dalvikvm(5221): GC freed 60 objects / 3128 bytes in 68ms 似乎在进入画廊时分配了越来越多的内存,但在退出画廊后释放的内存很少。我没有正确清理我的抽屉吗?对于drawables的arrayList中的每个元素,我调用setCallBacknull并将元素设置为null。这还不够吗? 渴望任何洞察力。
谢谢

您正在gallery 5或gallery 6中加载的图像可能太大而无法加载,并且超出了VM允许的最大大小

这些图像是从网络上获取的, 每台功率范围为300K至500K英寸 大小,并存储在 可提取的

从web加载的图像的kb文件大小与此没有直接关系。因为它们被转换成位图,所以对于常规ARGB图像,您需要计算每个图像的宽度*高度*4字节。以像素为单位的宽度和高度

位图使用本机堆,而本机堆通常不会显示在hprof中。hprof应该只显示对象的数量,即剩余的位图绘制表或位图

我在我的应用程序中使用此代码输出应用程序和本机堆当前使用的内存:

public static void logHeap(Class clazz) {
    Double allocated = new Double(Debug.getNativeHeapAllocatedSize())/new Double((1048576));
    Double available = new Double(Debug.getNativeHeapSize())/1048576.0);
    Double free = new Double(Debug.getNativeHeapFreeSize())/1048576.0);
    DecimalFormat df = new DecimalFormat();
    df.setMaximumFractionDigits(2);
    df.setMinimumFractionDigits(2);

    Log.d(APP, "debug. =================================");
    Log.d(APP, "debug.heap native: allocated " + df.format(allocated) + "MB of " + df.format(available) + "MB (" + df.format(free) + "MB free) in [" + clazz.getName().replaceAll("com.myapp.android.","") + "]");
    Log.d(APP, "debug.memory: allocated: " + df.format(new Double(Runtime.getRuntime().totalMemory()/1048576)) + "MB of " + df.format(new Double(Runtime.getRuntime().maxMemory()/1048576))+ "MB (" + df.format(new Double(Runtime.getRuntime().freeMemory()/1048576)) +"MB free)");
    System.gc();
    System.gc();

    // don't need to add the following lines, it's just an app specific handling in my app        
    if (allocated>=(new Double(Runtime.getRuntime().maxMemory())/new Double((1048576))-MEMORY_BUFFER_LIMIT_FOR_RESTART)) {
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}
在开发过程中,我在开始或完成活动时调用它

logHeap(this.getClass());
这里有一些信息性的链接——通常这里有很多关于这个主题的帖子

下面是Romain Guy Android Framework engineer制作的一张有用的幻灯片,内容涉及软引用、弱引用、简单缓存、图像处理: 以下是一些建议:

您是否使用inSampleSize选项?如果缩放图像,它会减少内存消耗

当不再需要图像时,应调用Bitmap.recycle。我认为这对你来说很重要


您最好知道getView的参数列表中的convertView总是空的。也就是说,gallery不重用内部的旧视图。

代码块不需要使用HTML标记。相反,使用随SO提供的内容。格式很好,谢谢你的编辑。由于某些原因,我无法使用提供的。。。编辑:好的,我现在明白了。4个空间…嗨,瑞安。画廊1的规模最大,可装载货物。此外,并不是某个特定的库崩溃。重要的是我已经参观过的画廊的数量。顺便说一句,每个多媒体资料的大小介于2.8 MB和4.4 MB之间。它不一定是多媒体资料的大小,而是图像的大小,除非您正在预加载所有图像。>通常是16Mb:对于显示分辨率较低的设备,通常是较旧的型号,它是16Mb,如G1,对于Nexus One等设备,HTC Desire的限制是24MB,而对于三星Galaxy S,它甚至更高,已经达到48MB。每堆的最大堆数app@Ryan-我从Web上获取所有图像,将它们放置在可绘制的arrayList中,然后继续加载保存库的活动。顺便说一句,对一张图片有限制吗?你预加载所有图片可能是问题所在。我在我正在编写的一个应用程序上尝试了类似的方法,如果我在drawables中预装了所有图像,我就会遇到内存不足异常。Mathias,我使用你的函数编辑了这个问题,并输出了一些结果。你怎么看这个?感谢仔细检查堆输出后,我意识到有些东西没有正确清除。我认为setCallBacknull和为元素设置null就足够了,但只有在应用recycle并清除内存之后。谢谢,Mathias。嗨,Rob,我也想到了回收,但不是为了你的案例/代码,因为你使用的是位图绘图工具,而不是位图本身。因此,您将哪些对象称为recyle
最后是什么?嗨,马泰斯。我调用了BitmapDrawable的getBitmap来获取位图,并对其应用了回收。此信息适用于Pre-Honeycom android。位图现在出现在你的Dalvik堆中。谢谢Fedor。在检查Mathias的logHeap函数的输出后,我意识到有些东西没有被清除。我应用了回收,内存被释放了。如果你允许,我将把答案归功于马蒂亚斯。谢谢!取样w00p w00p