如何修复 OutOfMemoryError android 工作室
how to fix OutOfMemoryError android studio
我有一个提取 7zip 文件的申请
我将这两个库用于提取
compile 'org.apache.commons:commons-compress:1.12'
compile files('libs/xz-1.3.jar')
这是我的代码
public void unzip() {
try {
File fc = new File(_location,"Driver2.7z");
System.out.println("file size"+fc.length());
//File fd = new File(_location,"Driver2.bin");
SevenZFile sevenZFile = new SevenZFile(fc);
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
System.out.println( "Unzipping " );
while(entry!=null){
System.out.println(entry.getName());
FileOutputStream out = new FileOutputStream(_location + entry.getName());
//FileOutputStream out = new FileOutputStream(entry.getName());
System.out.println(entry.getName());
byte[] content = new byte[(int) entry.getSize()];
System.out.println(entry.getName());
sevenZFile.read(content, 0, content.length);
System.out.println(entry.getName());
out.write(content);
System.out.println(entry.getName());
out.close();
entry = sevenZFile.getNextEntry();
System.out.println(entry.getName());
}
sevenZFile.close();
Log.d("Unzip", "Unzipping complete. path : " +_location );
} catch(Exception e) {
System.out.println("Decompress"+ "unzip"+ e.getMessage());
}
}
使用此代码我在某些设备上收到此错误
E/AndroidRuntime: FATAL EXCEPTION: Thread-218
Process: ir.milano.driver, PID: 30164
java.lang.OutOfMemoryError: Failed to allocate a 137881308 byte allocation with 4194304 free bytes and 129MB until OOM
at com.darkgamers.pepsiman.browser.mainmenu.DecompressFast.unzip(DecompressFast.java:38)
at ir.milano.driver.CopyFiles.run(CopyFiles.java:75)
问题出在这一行
byte[] content = new byte[(int) entry.getSize()];
您正在尝试从 zip 中提取一个大文件,大约 130MB。你不应该通过分配一个大的连续字节块来做到这一点。相反,您应该使用 Streams。
Streams 不会一次打开全部内容,而只是跟踪文件中的一个位置,允许一次只读取文件的一部分。您已经有一个输出流 FileOutputStream
您只需要找到相关的 API 调用来获取输入流并研究从输入流复制到输出。
或者,如果没有提供 Stream API,您可以使用 sevenZFile.read
在多个块中读取和写入,但缓冲区要小得多。
byte[] content = new byte[16 * 1024]; //fixed reasonable size buffer
while((int noBytesRead = sevenZFile.read(content, 0, content.size()) != -1){
//write the noBytesRead from content into your stream.
}
不要将整个 Zip 条目内容加载到内存中。以块的形式复制内容。 4K 的缓冲区大小 shown 在测试中是有效的。
此外,使用 try-with-resources and enhanced for 循环。
byte[] buffer = new byte[4096];
try (SevenZFile sevenZFile = new SevenZFile(fc)) {
for (SevenZArchiveEntry entry : sevenZFile.getEntries()) {
try (FileOutputStream out = new FileOutputStream(_location + entry.getName())) {
for (int len; (len = sevenZFile.read(buffer)) > 0; ) {
out.write(buffer, 0, len);
}
}
}
}
我有一个提取 7zip 文件的申请 我将这两个库用于提取
compile 'org.apache.commons:commons-compress:1.12'
compile files('libs/xz-1.3.jar')
这是我的代码
public void unzip() {
try {
File fc = new File(_location,"Driver2.7z");
System.out.println("file size"+fc.length());
//File fd = new File(_location,"Driver2.bin");
SevenZFile sevenZFile = new SevenZFile(fc);
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
System.out.println( "Unzipping " );
while(entry!=null){
System.out.println(entry.getName());
FileOutputStream out = new FileOutputStream(_location + entry.getName());
//FileOutputStream out = new FileOutputStream(entry.getName());
System.out.println(entry.getName());
byte[] content = new byte[(int) entry.getSize()];
System.out.println(entry.getName());
sevenZFile.read(content, 0, content.length);
System.out.println(entry.getName());
out.write(content);
System.out.println(entry.getName());
out.close();
entry = sevenZFile.getNextEntry();
System.out.println(entry.getName());
}
sevenZFile.close();
Log.d("Unzip", "Unzipping complete. path : " +_location );
} catch(Exception e) {
System.out.println("Decompress"+ "unzip"+ e.getMessage());
}
}
使用此代码我在某些设备上收到此错误
E/AndroidRuntime: FATAL EXCEPTION: Thread-218
Process: ir.milano.driver, PID: 30164
java.lang.OutOfMemoryError: Failed to allocate a 137881308 byte allocation with 4194304 free bytes and 129MB until OOM
at com.darkgamers.pepsiman.browser.mainmenu.DecompressFast.unzip(DecompressFast.java:38)
at ir.milano.driver.CopyFiles.run(CopyFiles.java:75)
问题出在这一行
byte[] content = new byte[(int) entry.getSize()];
您正在尝试从 zip 中提取一个大文件,大约 130MB。你不应该通过分配一个大的连续字节块来做到这一点。相反,您应该使用 Streams。
Streams 不会一次打开全部内容,而只是跟踪文件中的一个位置,允许一次只读取文件的一部分。您已经有一个输出流 FileOutputStream
您只需要找到相关的 API 调用来获取输入流并研究从输入流复制到输出。
或者,如果没有提供 Stream API,您可以使用 sevenZFile.read
在多个块中读取和写入,但缓冲区要小得多。
byte[] content = new byte[16 * 1024]; //fixed reasonable size buffer
while((int noBytesRead = sevenZFile.read(content, 0, content.size()) != -1){
//write the noBytesRead from content into your stream.
}
不要将整个 Zip 条目内容加载到内存中。以块的形式复制内容。 4K 的缓冲区大小 shown 在测试中是有效的。
此外,使用 try-with-resources and enhanced for 循环。
byte[] buffer = new byte[4096];
try (SevenZFile sevenZFile = new SevenZFile(fc)) {
for (SevenZArchiveEntry entry : sevenZFile.getEntries()) {
try (FileOutputStream out = new FileOutputStream(_location + entry.getName())) {
for (int len; (len = sevenZFile.read(buffer)) > 0; ) {
out.write(buffer, 0, len);
}
}
}
}