【问题标题】:JPG as background in Activity produces memory leakJPG 作为 Activity 中的背景会产生内存泄漏
【发布时间】:2011-09-20 19:27:16
【问题描述】:

我的小应用程序总是在第 5 次或第 6 次屏幕旋转后崩溃。定义了两种主要布局,一种用于横向,一种用于纵向。在花了一整天寻找内存泄漏后,我发现了问题:我有一个 JPG 定义为 Main-Activity 的背景。将JPG转换为PNG后,内存问题就解决了。

背景被定义为可绘制并在 main.xml 中定义。

当我在 2.2(模拟器)下测试应用时,问题没有出现,但在 2.3.1(也是模拟器)下,应用崩溃了。

有人能重现这个问题吗?


现在我将我的应用程序简化为以下代码:

package at.memtest;

import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.LinearLayout;

public class MemTestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

@Override
protected void onDestroy() {
    recycleImages();
    super.onDestroy();

}

@Override
protected void onPause() {
    recycleImages();
    super.onPause();
}


private void recycleImages() {
    final LinearLayout theView = (LinearLayout) findViewById(R.id.main_layout);
    if (theView != null) {
        final BitmapDrawable background = (BitmapDrawable) theView.getBackground();
        if (background != null) {
            background.getBitmap().recycle();
        }
    }
}
}

现在记忆保持不变... 你能想象这是避免内存泄漏所必需的吗? 正如我上面所说 - 我用作背景的图像是大约 220K 的 PNG。

【问题讨论】:

  • 这不是两次调用recycleImages,一次在OnPause,一次在onDestroy?

标签: android memory-leaks png jpeg


【解决方案1】:

我遇到了同样的问题。
我使用 .png 而不是 .jpg,这解决了问题。

【讨论】:

  • 我也使用 png 背景图片,但我有泄漏。所以还是很麻烦。
【解决方案2】:

您确定是文件格式有问题吗?试试这个:http://android-developers.blogspot.co.uk/2009/01/avoiding-memory-leaks.html

这可能是因为您没有像使用 PNG 那样快地耗尽内存。

【讨论】:

  • 谢谢,但我读了好几遍。我花了一天时间注释掉大部分程序代码。我做的最后一件事是将JPG更改为PNG并且堆保持不变......我知道我的解决方案听起来有点奇怪但是在旋转屏幕(在此之前导致问题之前)大约100次之后没有崩溃了.
  • 哦,伙计 - 你是对的。我做了另一个测试:15 分钟来回翻转方向,这意味着大约 900 个循环,然后它就崩溃了。从大约 2 小时开始,它正在翻转以下代码:
  • 抱歉,评论不完整:哦,伙计 - 你是对的。我做了另一个测试:15 分钟来回翻转方向,这意味着大约 900 个循环,然后它就崩溃了。但是使用以下代码,它从大约 2 小时开始翻转:@Override protected void onResume() { super.onResume(); System.gc(); } 你相信吗?现在堆保持不变。你以为我的内存问题只是模拟器造成的?
  • 我已经在处理大量图像的应用程序上做了大量工作,我可以向您保证,这不仅仅是一个模拟器问题。将应用程序放在设备上后检查 logcat,您会看到堆会不时调整大小。 Android 保证 16MB 堆空间,但如果您需要,大多数实现会给您更多。但是,有一个限制。一旦达到这个限制,你就会得到一个很好的 OutOfMemoryError。另外,永远不要依赖 System.gc()。
【解决方案3】:

我遇到了 jpg 背景图像的问题,这使我的应用在某些设备上也变得异常缓慢。不过,使用 png 并没有为我解决这个问题。我认为这可能与我为图像选择的高度压缩以节省空间有关,这可能会导致在运行时进行更多的解压缩工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 2019-01-08
    • 2011-01-17
    • 2019-03-12
    相关资源
    最近更新 更多