【问题标题】:OutOfMemoryError when I decompress RAR file on Android当我在 Android 上解压 RAR 文件时出现 OutOfMemoryError
【发布时间】:2012-12-16 01:50:28
【问题描述】:

我尝试这样做:Decompress Rar file in Android

但是我的一个 rar 文件无法解压。

日志:

01-01 17:41:32.121: E/AndroidRuntime(12799): FATAL EXCEPTION: Thread-771
01-01 17:41:32.121: E/AndroidRuntime(12799): java.lang.OutOfMemoryError
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.ppm.SubAllocator.startSubAllocator(SubAllocator.java:146)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.ppm.ModelPPM.decodeInit(ModelPPM.java:216)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.Unpack.readTables(Unpack.java:656)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.Unpack.unpack29(Unpack.java:165)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.unpack.Unpack.doUnpack(Unpack.java:120)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.Archive.doExtractFile(Archive.java:500)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.Archive.extractFile(Archive.java:442)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.testutil.ExtractArchive.extractArchive(ExtractArchive.java:73)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.github.junrar.testutil.ExtractArchive.extractArchive(ExtractArchive.java:29)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.letusread.util.DeCompressUtil.deCompress(DeCompressUtil.java:140)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at com.letusread.activity.FileListActivity$7.run(FileListActivity.java:338)
01-01 17:41:32.121: E/AndroidRuntime(12799):    at java.lang.Thread.run(Thread.java:856)
01-01 17:41:32.324: E/MobclickAgent(12799): onEndSession called before onStartSession

我的文件已解压缩,但我的应用程序崩溃了! 其他文件可以正常解压; 你能帮我解决这个错误吗??

【问题讨论】:

  • 您可能需要寻找一种不同的 RAR 解压缩实现,它更节省内存,因此更适合手机和平板电脑。
  • 只有876kb,包含一个txt文件和一个html文件:(
  • 你的堆大小超出限制尝试调试代码
  • 是的,但我能做些什么呢?
  • 调试你的代码并检查你的堆大小何时突然增加,如果它不合适的实现,那么也找到其他的

标签: java android rar


【解决方案1】:

似乎问题在于为提取文件分配堆内存。您可以在文件SubAllocator.java 的第146 行看到OutOfMemoryError。这一行是字节数组初始化:

heap = new byte[realAllocSize];

显然变量 realAllocSize 大于堆上的可用空闲内存(以字节为单位)。在 Android 设备上,每个 VM 的堆大小通常为 32 或 64 MB(每个活动都有自己的 VM)。似乎问题出在 junrar 库中,该库未针对在 Android 设备上使用进行优化并消耗大量内存。

【讨论】:

  • 是的,我刚刚查了源码,请问有什么好的方法吗?
  • 我会尝试确定 junrar 库消耗了多少内存。如果它远远超过可用的堆内存,那么最好找到另一个用于 rar 解压缩的库。但如果库分配的内存只有几 MB,则问题可能出在应用程序的另一部分,它消耗了太多内存。
  • 你看,大部分的rar文件都可以解压成功,但只有少数会抛出内存不足的异常,这就是我看不懂的原因。
  • 当我检查 junrar 源代码时,我认为用于提取文件的堆内存分配取决于 rar 文件头中的一些信息。这应该说明某些文件已成功提取,而有些则没有。也许它可能取决于压缩级别或其他一些在不同 rar 文件的标题中不同的属性。
  • 哦,但是其他一些应用可以轻松解压这个rar文件,我正在努力解决这个问题。
【解决方案2】:

实际上,这似乎是实现的一个错误。这是我用来避免问题的解决方法:

com.github.junrar.unpack.ppm.ModelPPM.java 中,第 196 行:MaxMB = unpackRead.getChar();

方法getChar,在一些奇怪的情况下,返回一个非常大的数字。这应该是由于 junrar 不支持的标头损坏或标头选项。

我的解决方法是检查 MaxMB 是否大于 1 并设置为 1。我已经使用此修复程序很长时间没有问题。

int MaxMB = 0;
if (reset) {
    MaxMB = unpackRead.getChar();
    if (MaxMB > 1) { //Workaround
        MaxMB = 1;
    }
}

【讨论】:

    猜你喜欢
    • 2012-03-16
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 2021-01-15
    相关资源
    最近更新 更多