Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.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
Java Android内存泄漏,来自资产的图像_Java_Android_Memory Leaks - Fatal编程技术网

Java Android内存泄漏,来自资产的图像

Java Android内存泄漏,来自资产的图像,java,android,memory-leaks,Java,Android,Memory Leaks,我从资产中获取图像并分配给imageView,一切正常,但当我看到堆内存大小时,当我一次又一次加载同一页时,它会不断增长,下面是我用来从资产文件夹获取图像的代码 private Bitmap getBitmapFromAsset(String strName) throws IOException { AssetManager assetManager = getAssets(); InputStream istr = assetManager.open(strName);

我从资产中获取图像并分配给imageView,一切正常,但当我看到堆内存大小时,当我一次又一次加载同一页时,它会不断增长,下面是我用来从资产文件夹获取图像的代码

private Bitmap getBitmapFromAsset(String strName) throws IOException
{
    AssetManager assetManager = getAssets();

    InputStream istr = assetManager.open(strName);
    Bitmap bitmap = BitmapFactory.decodeStream(istr);

    return bitmap;
}

    //Code to assign bitmap to imageview
    ImageView itemImage = (ImageView) findViewById(R.id.itemImage);
    try {
        Bitmap bm = getBitmapFromAsset("full/" + Uri.parse(menuItem.getFullImage()).getLastPathSegment());
        itemImage.setImageBitmap(bm);
    } catch (IOException e) {
        e.printStackTrace();
    }
这就是我正在做的一切,是否有任何地方需要回收位图?

一旦检查此项

使用完位图后,使用以下语句bm=null; 并编写System.gc();在ondestroy()中(如果需要,在onPause()中),并查看在ondestroy add中是否有效

   @Override
        public void onDestroy()
        {

            super.onDestroy();
            if(bm != null)
            {
                bm.recycle();

            }
}

另外,获取内存转储并分析转储使用情况。如果您需要这方面的帮助,请参考此视频

位图
对象一旦使用,您需要调用释放本机资源的
recycle()
方法

释放与此位图关联的本机对象,并清除对像素数据的引用。这将不会同步释放像素数据;它只允许在没有其他引用的情况下对其进行垃圾收集。位图被标记为“死”,这意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容。此操作无法反转,因此只有在确定位图没有其他用途时才应调用此操作。这是一个高级调用,通常不需要调用,因为当不再引用此位图时,正常GC进程将释放此内存


实际上,我正在使用一个由所有活动扩展的父活动,该活动已在LocationListener中注册,因此LocationListener正在防止活动被破坏。

除了已经说过的,我将关闭资产流,因为根据您在资产上运行的平台,资产可能不会自动关闭。
即使是这样,您也需要将文件描述符保留更长的时间。这是一个有限的资源,因此其他东西可能会因此而流失。

调用GC不是解决内存问题的正确方法。@Matsemann oh,很抱歉回答这个问题。不使用bm=null;解决问题?没问题,但您是如何使用的?public void onPause(){super.onPause();if(bm!=null){Log.i(“回收?”,“是”);bm.recycle();}}您使用位图bm=getBitmapFromAsset(“完整/”+Uri.parse(menuItem.getFullImage()).getLastPathSegment()了吗;是这样吗?或者您是否将其更改为bm=getBitmapFromAsset(“full/”+Uri.parse(menuItem.getFullImage()).getLastPathSegment());看这里。我经常使用它,但没有调用GC。在我看来,它没有任何用处,经常被用来掩盖罪恶;)谢谢尽管如此,你的答案对我来说并不适用。但它直接解决了我的问题。。。我使用了AssetFileDescriptor对象,但未关闭。。。所以它也被泄露了。。。我发现AssetFileDescriptor对象可以通过close()方法关闭。无论如何,我解决了我的问题。无论如何,谢谢。