Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GC.AddMemoryPressure equivalent in Java

Project: Java, JNI (C++), Android.

I'm going to manage native C++ object's lifetime by creating a managed wrapper class, which will hold a pointer to the native object (as a long member) and will delete the native object in it's overridden finalize() method. See this question for details.

The C++ object does not consume other types of resources, only memory. The memory footprint of the object is not extremely high, but it is essentially higher than 64 bit of a long in Java. Is there any way to tell Java's GC, that my wrapper is responsible for more than just a long value, and it's not a good idea to create millions of such objects before running garbage collection? In .NET there is a GC's AddMemoryPressure() method, which is there for exactly this purpose. Is there an equivalent in Java?

like image 344
Alex Che Avatar asked Jul 16 '11 09:07

Alex Che


People also ask

What is GC roots in Java?

Figure 2.2: GC roots are objects that are themselves referenced by the JVM and thus keep every other object from being garbage-collected. Therefore, a simple Java application has the following GC roots: Local variables in the main method. The main thread. Static variables of the main class.

What is full GC in Java?

Full GC is an important phase in the garbage collection process. During this full GC phase, garbage is collected from all the regions in the JVM heap (Young, Old, Perm, Metaspace). During this phase, the JVM is paused.

How does GC work in Java?

Garbage collection in Java is the process by which Java programs perform automatic memory management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM for short. When Java programs run on the JVM, objects are created on the heap, which is a portion of memory dedicated to the program.

What is Java GC heap?

Java garbage collection is the process by which Java programs perform automatic memory management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM for short. When Java programs run on the JVM, objects are created on the heap, which is a portion of memory dedicated to the program.


2 Answers

I believe that native memory is allocated outside the scope of Java's heap size. Meaning, you don't have to worry about your allocation taking memory away from the value you reserved using -Xmx<size>.

That being said, you could use ByteBuffer.allocateDirect() to allocate a buffer and GetDirectBufferAddress to access it from your native code. You can control the size of the direct memory heap using -XX:MaxDirectMemorySize=<size>

like image 44
Gili Avatar answered Oct 17 '22 06:10

Gili


After some more googling, I've found a good article from IBM Research Center.

Briefly, they recommend using Java heap instead of native heap for native objects. This way memory pressure on JVM garbage collector is more realistic for the native objects, referenced from Java code through handles.

To achieve this, one needs to override the default C++ heap allocation and deallocation functions: operator new and operator delete. In the operator new, if JVM is available (JNI_OnLoad has been already called), then the one calls NewByteArray and GetByteArrayElements, which returns the allocated memory needed. To protect the created ByteArray from being garbage collected, the one also need to create a NewGlobalRef to it, and store it e.g. in the same allocated memory block. In this case, we need to allocate as much memory as requested, plus the memory for the references. In the operator delete, the one needs to DeleteGlobalRef and ReleaseByteArrayElements. In case JVM is not available, the one uses native malloc and free functions instead.

like image 109
Alex Che Avatar answered Oct 17 '22 06:10

Alex Che