Android,关注VM堆大小

时间:2011-04-06 15:14:36

标签: android bitmap heap virtual-machine

使用完成的产品进行一些测试后,我发现我拥有的硬件设备都有大型VM堆。

最低为32MB。

我的应用程序是一个内存密集型应用程序,它可以加载一堆高质量的alpha图像,并将它们作为动画绘制到画布上。最多可以加载两组(一组用于当前动画,另一组用于下一组)

我现在担心将我的一台设备上的VM堆大小减少到16MB,实际上它不会在堆大小很小的设备上运行。

由于我无法对图像的大小做很多事情,并且我无法减少图像数量,因此我会问我如何以较不严格的内存限制来解决相同的结果?

由于

2 个答案:

答案 0 :(得分:0)

当你说高品质时,你的意思是高分辨率吗?我的建议是你只在内存中存储你需要在屏幕上显示的内容,并将其余内容存储在文件系统中。然后,您可以在后台以块的形式处理它。不确定这是否适合你,我真的不明白你的应用程序做了什么。

答案 1 :(得分:0)

您可以使用此方法解码图像。它可能会让它们变轻。请记住,当图像显示增加记忆消耗时,图像会变成位图。

public static Bitmap decode(byte[] imageByteArray, int width, int height) {
    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length,
            o);

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp / 2 < width || height_tmp / 2 < height)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // Decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    o2.inTempStorage = new byte[Math.max(16 * 1024, width * height * 4)];
    return BitmapFactory.decodeByteArray(imageByteArray, 0,
            imageByteArray.length, o2);

    // return BitmapFactory.decodeByteArray(imageByteArray, 0,
    // imageByteArray.length);
}

,其中

width - imageView可能具有的MAX宽度(以像素为单位)。 height - imageView可能具有的最大像素高度。

这样,位图将变得更轻,应用程序可能会消耗更少的内存。

(注意:我复制了这个方法并对其进行了一些修改,我不记得原来的问题所以我不能把它放到网址上)

我用它来扫描字节数组中的图像,我只是在显示它们之前解码它们。

现在,就像詹姆斯L所说的那样,最好将图像保存在文件系统中,只在需要时才带入内存,但如果你不这样做(我的情况)。你可以下载图像:

public static byte[] getBytes(InputStream is) throws IOException {

    int len;
    int size = 1024;
    byte[] buf;

    if (is instanceof ByteArrayInputStream) {
        size = is.available();
        buf = new byte[size];
        len = is.read(buf, 0, size);
    } else {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        buf = new byte[size];
        while ((len = is.read(buf, 0, size)) != -1)
            bos.write(buf, 0, len);
        buf = bos.toByteArray();
    }
    return buf;
}

public static byte[] downloadFileByteArray(String fileUrl)
            throws IOException, MalformedURLException {

    URL myFileUrl = null;

    myFileUrl = new URL(fileUrl);

    HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
    conn.setDoInput(true);
    conn.connect();
    InputStream is = conn.getInputStream();

    return getBytes(is);
}

如果你已经拥有了内存中的图像,你可以通过使用我提供的方法将它们变成字节数组。

除此之外(并调用System.gc()),你可以做的事情不多(我知道)。也许在onPause()和onDestroy()中删除BMP并在必要时在onResume()中重新构造它们。