You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I know this is an old project with little activity, but I'm leaving this issue here as a warning to future users. There is a massive memory leak in this wrapper.
Basic Info
I'm using Mojang's LevelDB library, which is based on the latest version of LevelDB 1.18, but supports Windows and adds zlib compression. On both Windows and Ubuntu 14.04 (only two platforms I have to test with), I encounter a very large memory leak where the number of objects allocated outside the Java heap continues to grow until eventually the program uses up all system RAM. I spent 2 days looking into this issue until I finally figured out it was due to my complete ignorance of what this JNA wrapper does behind the scenes.
The Problem
LevelDB.get is the main cause of the memory leak, though there may be smaller leaks littered throughout the wrapper. The native LevelDB library returns an malloc'd byte array to the wrapper, which means it's up to the wrapper to free the byte array. However, this wrapper's LevelDB.get method returns a copy of the native byte array allocated by the LevelDB library, but doesn't free the original native byte array. This means the original byte array malloc'd by the native LevelDB library is never freed and persists outside the Java heap, completely invisible to the Java garbage collector.
JNA will not automatically free the byte arrays returned by the native LevelDB library or pointed to by a PointerToReference. These arrays must be freed manually.
Solutions
For future users, fork this repo and change LevelDB.get using one of the following solutions:
Solution 1
Modify the LevelDB.get function to clear the data being pointed to before returning the copied byte array, like so:
This option will have a little less overhead as Java doesn't have to copy the original byte array; however, the ByteBuffer returned is a DirectByteBuffer, which may not be ideal for some applications and use-case scenarios.
The text was updated successfully, but these errors were encountered:
jocopa3
changed the title
Easy Potential for a Memory Leak
Nasty Memory Leak
Jan 25, 2017
I know this is an old project with little activity, but I'm leaving this issue here as a warning to future users. There is a massive memory leak in this wrapper.
Basic Info
I'm using Mojang's LevelDB library, which is based on the latest version of LevelDB 1.18, but supports Windows and adds zlib compression. On both Windows and Ubuntu 14.04 (only two platforms I have to test with), I encounter a very large memory leak where the number of objects allocated outside the Java heap continues to grow until eventually the program uses up all system RAM. I spent 2 days looking into this issue until I finally figured out it was due to my complete ignorance of what this JNA wrapper does behind the scenes.
The Problem
LevelDB.get
is the main cause of the memory leak, though there may be smaller leaks littered throughout the wrapper. The native LevelDB library returns anmalloc
'd byte array to the wrapper, which means it's up to the wrapper to free the byte array. However, this wrapper'sLevelDB.get
method returns a copy of the native byte array allocated by the LevelDB library, but doesn't free the original native byte array. This means the original byte arraymalloc
'd by the native LevelDB library is never freed and persists outside the Java heap, completely invisible to the Java garbage collector.JNA will not automatically free the byte arrays returned by the native LevelDB library or pointed to by a
PointerToReference
. These arrays must be freed manually.Solutions
For future users, fork this repo and change
LevelDB.get
using one of the following solutions:Solution 1
Modify the
LevelDB.get
function to clear the data being pointed to before returning the copied byte array, like so:This option also has lots of overhead as Java still has to copy the original byte array to the Java heap.
Solution 2
Modify the
LevelDB.get
function to return aByteBuffer
mapped to the original byte data using:This option will have a little less overhead as Java doesn't have to copy the original byte array; however, the
ByteBuffer
returned is aDirectByteBuffer
, which may not be ideal for some applications and use-case scenarios.The text was updated successfully, but these errors were encountered: