venbab
venbab

Reputation: 11

How to decompress a RAR file in Android application with out of memory exception?

I am writing an Android application for decompressing RAR files with the help of JunRar library. But during decompression of some type of RAR files, out of memory exceptions occur.

Could somebody please help me to resolve this issue.

I know, there is a problem with JunRar library, but if anyone found solution, please let me know.

My analysis:

If a RAR file is compressed with a PPM algorithm, this out of memory exception occurs because an attempt is made to allocate more memory than Android device VM has.

startSubAllocator is allocating more memory than Android VM has by new byte [100] MB bytes. That exceeds available RAM of 96 MB of Android VM.

Logs attached

java.lang.OutOfMemoryError

com.github.junrar.unpack.ppm.SubAllocator.startSubAllocator(SubAllocator.java:146)
com.github.junrar.unpack.ppm.ModelPPM.decodeInit(ModelPPM.java:216)
com.github.junrar.unpack.Unpack.readTables(Unpack.java:656)
com.github.junrar.unpack.Unpack.unpack29(Unpack.java:165)
com.github.junrar.unpack.Unpack.doUnpack(Unpack.java:120)
com.github.junrar.Archive.doExtractFile(Archive.java:500)
com.github.junrar.Archive.extractFile(Archive.java:442)
com.github.junrar.testutil.ExtractArchive.extractArchive(ExtractArchive.java:73)
com.github.junrar.testutil.ExtractArchive.extractArchive(ExtractArchive.java:29)
com.letusread.util.DeCompressUtil.deCompress(DeCompressUtil.java:140)
com.letusread.activity.FileListActivity$7.run(FileListActivity.java:338)
java.lang.Thread.run(Thread.java:856)

Upvotes: 1

Views: 2281

Answers (2)

yopablo
yopablo

Reputation: 68

In fact, it seems to be a bug of the implementation. This is the workaround I have used in order to avoid the problem:

In com.github.junrar.unpack.ppm.ModelPPM.java , line 196: MaxMB = unpackRead.getChar();

the method getChar, in some weird situations, return a very big number. It should be due to a broken header or a header option not supported by junrar.

My workaround was to check if MaxMB was greater than 1 and set to 1. I've been using this fix for a long time without problems.

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

Upvotes: 1

Mofi
Mofi

Reputation: 49096

Help of WinRAR contains on page with title Advanced compression parameters the explanation:

Text compression/Memory to use, MB
Memory in megabytes allocated for PPM (can be 1-128). Higher values may increase the compression ratio, but note that PPM uses an equal memory size both to compress and decompress, so if you allocate too much memory when creating an archive, other people may have problems when unpacking it on a computer with less memory installed. If this field is set to 0, WinRAR will choose the memory size automatically.

The help page with title Switch -MC - set advanced compression parameters and text file Rar.txt (manual for console version) contain a similar statement on memory requirements for advanced text compression.

128 MB of free (perhaps even continuous) memory is needed for unpacking a RAR archive which was created using advanced text compression with 128 MB memory usage. Nothing can be done to extract files from such a RAR archive if there is not enough free memory.


Text file Rar.txt contains also information about memory requirements for solid archives on compression and decompression (switch -md):

For RAR 4.x archive format the dictionary size can be:
64 KB, 128 KB, 256 KB, 512 KB, 1 MB, 2 MB, 4 MB.

For RAR 5.0 archive format the dictionary size can be:
128 KB, 256 KB, 512 KB, 1 MB, 2 MB, 4 MB, 8 MB, 16 MB, 32 MB, 64 MB, 128 MB, 256 MB, 512 MB, 1 GB.

When archiving, RAR needs about 6x memory of specified dictionary size, so 512 MB and 1 GB sizes are available in 64 bit RAR version only. When extracting, slightly more than a single dictionary size is allocated, so both 32 and 64 bit versions can unpack archives with all dictionaries up to and including 1 GB.


To answer your question: You cannot do anything in your application if a RAR archive was created on a Windows PC using excessive memory and there is not enough free memory for decompression. Alternate decompression algorithms with less memory usage for those RAR archives do not exist.

Upvotes: 1

Related Questions