borisbrodski / sevenzipjbinding

7-Zip-JBinding
http://sevenzipjbind.sourceforge.net/
Other
176 stars 50 forks source link

Prevent memory leak by deleting JNI local ref #66

Open CelestiaTheDryad opened 1 year ago

CelestiaTheDryad commented 1 year ago

While extracting archives, the streams used could not be garbage collected until the entire extract operation finished. This could be a problem when extracting large archives as the stream objects may eat all available heap space. This was fixed by deleting the JNI local ref shortly after creating the JNI global ref.

borisbrodski commented 1 year ago

Thank you for your kind contribution.

Have you actually checked, that this DeleteLocalRef() makes a difference? (JNI removes all local references automatically on method return)

CelestiaTheDryad commented 1 year ago

The refs would be deleted when the method returns. But if you are extracting a large number of files, the held memory for each stream can be a problem until then.

In my case, I was extracting ~600k files, and each used a buffered input stream with an 8 KB buffer. That would've required over 4 GB heap space to complete, and caused my client to fail as it did not have that much.

Adding the DeleteLocalRef() allowed the operation to complete, and I verified with a heap dump that no refs were being retained past their use.