【问题标题】:GridView Out of Memory Universal Image LoaderGridView 内存不足通用图像加载器
【发布时间】:2014-08-12 19:35:13
【问题描述】:

我的一些用户(主要使用三星设备)在使用网格视图的应用程序时遇到内存不足错误。请注意,我无法在我的任何设备 (Nexus) 上重现此内容

根据 Universal Image Loader 文档:

If you often got OutOfMemoryError in your app using Universal Image Loader then:

Disable caching in memory. If OOM is still occurs then it's a defect of your app. 

由于我已经尝试禁用 cacheInMemory,显然我的应用程序存在缺陷,但我看不出问题出在哪里。网格一次最多显示 12 个项目(整个列表中大约 1400 个)。我没有设置任何 ImageLoaderConfiguration 设置,也许我应该这样做?

private ArrayList<Theme> mThemes;
private static DisplayImageOptions options;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mRootView = inflater.inflate(R.layout.ac_image_grid, container, false);
    options = new DisplayImageOptions.Builder()
            .showStubImage(R.drawable.ic_stub)
            .showImageForEmptyUri(R.drawable.ic_empty)
            .showImageOnFail(R.drawable.ic_error)
            .cacheInMemory(false)
            .cacheOnDisc(true)
            .bitmapConfig(Bitmap.Config.RGB_565)
            .build();
    }
    public class ImageAdapter extends BaseAdapter {
    @Override
    public int getCount() {
        int result = 0;
        if (mThemes != null) {
            result = mThemes.size();
        }
        return result;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ImageView imageView;

        if (convertView == null) {
            imageView = (ImageView) getActivity().getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
        } else {
            imageView = (ImageView) convertView;
        }

        Theme theme = mThemes.get(position);

        imageLoader.displayImage(theme.getImageURL(), imageView, options); ***ERROR occurs here

        return imageView;
    }
}

ac_image_grid 看起来像:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/grid_relative"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ptr_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
<GridView 
    android:id="@+id/gridview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:horizontalSpacing="4dip"
    android:numColumns="auto_fit"
    android:columnWidth="150dip"
    android:stretchMode="columnWidth"
    android:verticalSpacing="4dip"
    android:padding="4dip" />
    </uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout>
</RelativeLayout>

item_grid_image:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:contentDescription="ImgDesc"
    android:scaleType="centerCrop" />

编辑:是否从模拟器转储(仍然无法重现错误)并有以下内存泄漏嫌疑人(我不知道它们的意思)。

 One instance of "android.widget.GridView" loaded by "<system class loader>" occupies 8,656,352 (15.66%) bytes. The memory is accumulated in one instance of "android.widget.GridView" loaded by "<system class loader>".

Keywords
android.widget.GridView

还有

One instance of "android.widget.GridView" loaded by "<system class loader>" occupies 7,214,272 (13.05%) bytes. The memory is accumulated in one instance of "android.view.View[]" loaded by "<system class loader>".

Keywords
android.view.View[]
android.widget.GridView

购买了一台受影响的设备,这是日志:

06-28 00:15:28.797    5204-5204/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 12.665MB for 1440016-byte allocation
06-28 00:15:28.857    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 861K, 13% free 10350K/11783K, paused 2ms+2ms
06-28 00:15:28.937    5204-5228/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 13.869MB for 720016-byte allocation
06-28 00:15:28.987    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 186K, 5% free 12653K/13255K, paused 2ms+3ms
06-28 00:15:29.037    5204-5230/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 17.556MB for 720016-byte allocation
06-28 00:15:29.087    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 914K, 10% free 14088K/15495K, paused 1ms+3ms
06-28 00:15:29.127    5204-5230/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 19.443MB for 720016-byte allocation
06-28 00:15:29.237    5204-5228/com.test.app.d D/dalvikvm﹕ GC_FOR_ALLOC freed 1180K, 9% free 18274K/19911K, paused 24ms
06-28 00:15:29.297    5204-5228/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 26.879MB for 720016-byte allocation
06-28 00:15:29.347    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 344K, 4% free 22556K/23431K, paused 2ms+2ms
06-28 00:15:29.437    5204-5226/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 32.572MB for 720016-byte allocation
06-28 00:15:29.497    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 615K, 4% free 28883K/29959K, paused 3ms+4ms
06-28 00:15:29.577    5204-5228/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 38.750MB for 720016-byte allocation
06-28 00:15:29.617    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 545K, 4% free 33738K/34887K, paused 2ms+3ms
06-28 00:15:29.707    5204-5230/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 43.490MB for 720016-byte allocation
06-28 00:15:29.777    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 551K, 3% free 40900K/41927K, paused 2ms+3ms
06-28 00:15:29.877    5204-5228/com.test.app.d I/dalvikvm-heap﹕ Grow heap (frag case) to 50.485MB for 720016-byte allocation
06-28 00:15:29.937    5204-5206/com.test.app.d D/dalvikvm﹕ GC_CONCURRENT freed 613K, 3% free 45689K/46855K, paused 1ms+4ms

【问题讨论】:

  • 你的 ImageView XML 布局是什么?
  • 添加了 XML 布局 @NOSTRA
  • 我不能说什么可以解决您的问题,但您可以尝试添加.imageScaleType(ImageScaleType.EXACTLY)。您也可以在 ImageView 布局中添加近似的 maxWidthmaxHeight。但无论如何,您需要在任何设备上重现此问题并使用 MemoryAnalizer 分析内存转储。
  • 尝试更改图像比例。没有效果,但我粘贴了一个日志文件。

标签: android gridview bitmap out-of-memory universal-image-loader


【解决方案1】:

我知道我来晚了,但我喜欢解决这类问题。首先,您的问题仍然存在吗?

一些建议 ->

首先,您的 GC 比正常中断更频繁。这也会中断主线程。所以我们只需要弄清楚为什么会一次又一次地调用GC。

  • 首先检查您的图像尺寸。而且你正在缓存然后可能是磁盘上的问题,因为每次它都是从磁盘获取图像。
  • 尝试使用 android MAT 和层次结构查看器工具。可能会有帮助。

我需要您的回答才能了解更多信息。

【讨论】:

  • 每张图片都是大约 7kb 的 jpg 并以大约 100dp 的正方形显示。我最终通过增加每个图像的大小来解决这个问题,这样屏幕上一次只有大约 12-16 个(而不是 40 个)。我将此归因于内存不足?我尝试使用层次结构查看器工具,但找不到任何有用的东西(但这是我第一次尝试)。如果您愿意深入挖掘,我可以提取更多信息,请告诉我。
  • 确定 ...您是否也尝试过 MAT 工具??在 Mat 中,您可以找到占用大部分内存的对象,从而导致 GC 。要了解更多信息,您可以在 MAT 上观看 google I/O 2011 视频 ...youtube.com/watch?v=_CruQY55HOk.....I 如果可能的话,也可以查看代码。
  • 是的,我以前发现过那个视频,它非常有帮助。至于查看代码,我不确定我们是否能找到一种简单的方法来做到这一点。
  • 好的...所以我想为了进一步帮助您,我需要查看您的代码...所以有没有可能我可以查看您的代码??
  • 我想不出一个简单的方法。你需要看什么?
【解决方案2】:

通过简单地减少低内存设备在任何时候屏幕上的位图数量来解决这个问题。 Nostra 在 github 网站上发布的解决方案有所帮助,但并未完全解决。

【讨论】:

    猜你喜欢
    • 2016-07-19
    • 2019-10-23
    • 2016-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2014-09-15
    相关资源
    最近更新 更多