gpt4 book ai didi

java - 在 byteArray 中存储图像时的内存问题

转载 作者:行者123 更新时间:2023-11-30 03:26:27 25 4
gpt4 key购买 nike

我有一个需要快速访问大量图像的应用程序,因此我需要以某种方式将这些图像加载到内存中。这样做是因为位图使用了超过 100MB 的 RAM,这是完全不可能的,所以我选择将 jpg 文件读入内存,并将它们存储在 byteArray 中。然后我解码它们并根据需要将它们写入 Canvas 。这非常有效,消除了缓慢的磁盘访问,同时还遵守内存限制。

但是,内存使用对我来说似乎是“关闭”的。我正在存储 450 个 jpg,每个文件大小约为 33kb。这总共有大约 15MB 的数据。但是,根据 Eclipse DDMS 和 Android(在物理设备上)的报告,该应用程序持续运行在 35MB 到 40MB 的 RAM 之间。我已经尝试修改加载了多少 jpg,并且应用程序使用的 RAM 每 jpg 往往会减少大约 60-70kb,这表明每个图像在 RAM 中存储了两次。内存使用量不会波动,这意味着不存在实际的“泄漏”。

相关加载代码如下:

private byte[][] bitmapArray = new byte[totalFrames][];
for (int x=0; x<totalFrames; x++) {
File file = null;
if (cWidth <= cHeight){
file = new File(directory + "/f"+x+".jpg");
} else {
file = new File(directory + "/f"+x+"-land.jpg");
}
bitmapArray[x] = getBytesFromFile(file);
imagesLoaded = x + 1;
}


public byte[] getBytesFromFile(File file) {
byte[] bytes = null;
try {

InputStream is = new FileInputStream(file);
long length = file.length();

bytes = new byte[(int) length];

int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
offset += numRead;
}

if (offset < bytes.length) {
throw new IOException("Could not completely read file " + file.getName());
}

is.close();
} catch (IOException e) {
//TODO Write your catch method here
}
return bytes;
}

最终,它们会像这样写入屏幕:

SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
int canvasWidth = c.getWidth();
int canvasHeight = c.getHeight();
Rect destinationRect = new Rect();
destinationRect.set(0, 0, canvasWidth, canvasHeight);
c.drawBitmap(BitmapFactory.decodeByteArray(bitmapArray[bgcycle], 0, bitmapArray[bgcycle].length), null, destinationRect, null);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}

我是否正确认为这里发生了某种重复?还是像这样将 jpg 存储在 byteArray 中会涉及很多开销?

最佳答案

在 RAM 中存储字节与在硬盘驱动器上存储数据是非常不同的……它有更多的开销。对对象的引用以及字节数组结构都占用额外的内存。所有额外的内存并没有真正的单一来源,但请记住,将文件加载到 RAM 中通常会占用 2 ~ 3 倍的空间(根据经验,恐怕我不能在这里引用任何文档)。

考虑一下:

File F = //Some file here (Less than 2 GB please)
FileInputStream fIn = new FileInputStream(F);
ByteArrayOutputStream bOut = new ByteArrayOutputStream(((int)F.length()) + 1);

int r;
byte[] buf = new byte[32 * 1000];

while((r = fIn.read(buf) != -1){
bOut.write(buf, 0, r);
}

//Do a memory measurement at this point. You'll see your using nearly 3x the memory in RAM compared to the file.
//If your actually gonna try this, remember to surround with try-catch and close the streams as appropriate.

另请记住,未使用的内存不会立即清除。方法 getBytesFromFile() 可能会返回一个字节数组的副本,这会导致可能不会立即被垃圾回收的内存重复。如果您想安全起见,请检查方法 getBytesFromFile(file) 是否泄漏了任何应该清理的引用。它不会显示为内存泄漏,因为您只调用它有限次数。

关于java - 在 byteArray 中存储图像时的内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18152100/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com