Java memory Management for JNI - java

I have two questions :
What if I have a JNI call to a method and the JNI method leaks memory. Once this method completes will the JVM Garbage collector be able to get that memory back. I heard that the JVM does not manage the Heap Space used by JNI ? But the memory used by JNI is a part of the memory used by the Java process ?
Is it absolutely necessary to use JNI to achieve IPC ? What are the other popular Java techniques or is there a Open Source Library to achieve Shared memory in Java ?

No: "the JNI framework does not provide any automatic garbage collection for non-JVM memory resources allocated by code executing on the native side" (Wikipedia).
No, Java has sockets and indeed ProcessBuilder. Shared memory can be achieved with MappedByteBuffer.

You need deallocate any os resource created in native code, such as File Descriptor, memory address (allocate by malloc. etc) because they are not binding with any jvm instance.
You can consider use Memory-Mapped Files (sample).
You can use RPCs (between computer and computer) in IPC context, such as socket, web service, JMS, etc.

in all likelihood yes - though i'm not entirely sure whether there doesn't exist a way to clear that memory.
take a look at ProcessBuilder - it might be of some help to exclude JNI to achieve IPC.

Related

Does Garbage Collector run in JVM created from C++?

I have a C++ codebase, in which I'm using JNI to create a JVM and occasionally interact with a library implemented in Java. I'm curious whether, in this use case, Java's garbage collector will still reliably run and clean up?
Most of the information that I find online about JNI seems to be about the "opposite" use case, where people generally appear to have mainly Java code, which sometimes interacts with native code through JNI. For such a use case, I find for example the following online:
The automatic garbage collection of local references that are no longer in scope prevents memory leaks in most situations. This automatic garbage collection occurs when a native thread returns to Java (native methods) or detaches from the JVM (Invocation API). Local reference memory leaks are possible if automatic garbage collection does not occur. A memory leak might occur if a native method does not return to the JVM, or if a program that uses the Invocation API does not detach from the JVM.
I'm not sure what exactly "returns to Java" in this context means. Is just occasionally calling into Java-based methods from C++ sufficient, does that already count as "returning to Java"? If not, are there any ways to make sure that the garbage collector gets a chance to run in my use case?
The JVM created with JNI is a full JVM, including GC.
Think of it this way: The java command that you normally use to run Java programs, is nothing but a small JNI program that creates a JVM, locates the class named on the command-line, and makes a static call to the main(String[]) method.

Do Java access modifiers use permissions from the operating system or is the access controlled by Java itself?

I have found many, many resources about Java access modifiers that explain what they are and how to use them and why to use them and when to use them. But, I have found no discussion on how they work or how much Java depends on the operating system to enforce them and if so, how much the enforcement is dependent on which operating system is used. Possibly, I am using the wrong search terms.
Basically it's 100% controlled by Java and the JVM, and the OS has nothing to do with it. There's no hardware intervention (for example) in controlling access to a private field. It's just the software running on the JVM doesn't let you (directly, you can do it with reflection) read the memory location of that field.
AFAIK, all Java objects are allocated on the heap which is just ordinary memory that can be read or written. Some parts of the JVM might actually be protect by the OS -- executable memory for example, or the stack. But Java is a unified memory system where all memory, all objects and their fields, go in the same OS "bucket" of memory, and that's the heap.
I think this is sometimes called a SISD model -- "single instruction single data," where the "single data" is just the heap. And yes I'm ignoring the SIMD instructions that Intel has because those instructions are relatively rare.

Monitor jvm heap size from C++

Is there a way to programmatically get the current jvm stats such as classes loaded or current heap size from C++? I know there are many tools to do so but I would like to integrate this with another application that would read these statistics from time to time.
You can have a look at JVMTI and JNI.
JVMTI allows you to attach a native agent to a Java application, with loads of low-level functionalities like heap traversals, etc. It also contains "Garbage Collection Start" & "Garbage Collection Finish" events, which could be used as starting points.
JNI allows you to call Java functions from native code (and vic-versa). I could imagine that you could use this technique to obtain information from ManagementFactory or some similar Java class that provides the needed information. This post contains a complete example on how to call static Java methods via JNI, which should be a good starting point.

Limit resource utilization of JNA calls without changing dll

How can you prevent a JNA method-call from exceeding thresholds for CPU utilization, thread-counts, and memory limits?
Background:
I'm working on a safety critical application and one of the non-safety-critical features requires the use of a library written in C. The dlls have been given to me as a black-box and there's no chance that I'll get access to the source code beyond the java interface files. Is there a way to limit the CPU usage, thread-count, and memory used by the JNA code?
See ulimit and sysctl, which are applicable to your overall JVM process (or any other process, for that matter).
It's not readily possible to segment parts of your JVM which are making native accesses via JNA from those that aren't, though.
You should run some profiling while you exercise your shared library to figure out what resources it does use, so you can focus on setting limits around those (lsof or strace would be used on linux, I'm not sure of the equivalent on windows).
For most operating systems you must either call your C code from a new thread or new process. I would recommend calling it from a new process as then you can sandbox it easier and deeper. Typically on a Unix like system one switches to a new user set aside for the service and that has user resource limits on it. However, on Linux one can use user namespaces and cgroups for more dynamic and flexible sandboxing. On Microsoft Windows one typically uses Job objects for resource sandboxing but permissions based sandboxing is more complicated (a lot of Windows is easily sandboxable with access controls but the GUI and window messaging parts make things complicated and annoying).

Java without gc - io

I would like to run a Java program with garbage collection switched off. Managing memory in my own code is not so difficult.
However the program needs quite a lot of I/O.
Is there any way (short of using JNI for all I/O operations) that I could achieve this using pure Java?
Thanks
Daniel
What you are trying to achieve is frequently done in investment banking to develop low-latency real-time systems.
To avoid GC you simply need to make sure not to allocate memory after the startup and warm-up phase of your application.
As you seem to have noticed Java NIO internally does unwanted memory allocation.
Unfortunately, you have no choice but write JNI replacements for the problematic calls.
You need at least to write a replacement for the NIO Selector.
You will have to avoid using most of the Java libraries due to similar unwanted memory allocations.
For example you will have to avoid using immutable object like String, avoid Boxing, re-implement Collections that preallocate enough entries for the whole lifetime of your program.
Writing Java code this way is not easy, but certainly possible.
I am developing a platform to do just so.
Managing memory in my own code is not
so difficult.
It's not difficult - It's impossible. For example:
public void foo() {
Object o = new Object();
// free(o); // Doh! No "free" keyword in Java.
}
Without the aid of the garbage collector how can the memory consumed by o be reclaimed?
I'm assuming from your question that you might want to avoid the sporadic pauses caused by garbage collection due to the high level of I/O being performed by your app. If this is the case there are techniques for minimising the number of objects created (e.g. re-using objects from a pool). You could also consider enabling the Concurrent Mark Sweep Collector.
The concurrent mark sweep collector,
also known as the concurrent collector
or CMS, is targeted at applications
that are sensitive to garbage
collection pauses.
It's very hard (but not impossible) to disable GC in a JVM.
Look at the JNI "critical" functions for hints.
You can also essentially ensure you don't GC by not allocating any more objects (write a JVMTI agent that slaps you if you do, and instrument your code).
Finally, you can force a fatal OutOfMemoryError by ensuring that every object you allocate is never freed, thus when you hit -Xmx memory used, you'll fall over as GC won't be able to reclaim anything (mind you, you'll GC one or more times at this point before you fall over in a heap).
The real question is why you'd want to? What upside do you see in doing it? Is it for realtime? If so, I'd consider looking at one of the several realtime JVMs available on the market (Oracle, IBM, & others all sell them). I can't honestly think of another reason to do this while still using Java.
The only way you are going to be able to turn off garbage collection is to modify the JVM. This is should be feasible with OpenJDK 6 codebase.
However, the what you will get at the end is a JVM that leaks memory like crazy, with no reasonable hope of fixing the leaks. The Java class library APIs are designed and implemented on the assumption that there is a GC taking care of memory management. This is so fundamental that any serious attempt to "fix" it would lead to a language / library that is not recognizable as Java.
If you want a non-garbage collected language, use C or C++.
Modern JVM's are so good at handling short-lived objects that any scheme you devise on your own will be slower.
This is because the objects you handle yourself will become long-lived and receive extra deluxe treatment from the JVM in terms of being moved around etc. Of course, this is by the garbage collector, which you want to turn off, but you can do very little without any gc.
So, before you start considering what optimization to use, then establish a baseline where you have a large unoptimized, program and profile it. Then do your tweaks, and see if it helps, but you will never know if you do not have a baseline.
As other people have mentioned you can't disable the GC. However, you can choose to use the experimental 'Epsilon' garbage collector which will never actually perform any garbage collections. Warning: it will crash if your JVM runs out of memory (because it's not doing any garbage collections).
There's more info (including the command-line switch to use) at:
http://openjdk.java.net/jeps/318
Good luck!
GarbageCollection is automated memory management in java.So you can not disable GC
Since you say, "its all about predictability not straight line speed," you should look at using a realtime Java system with deterministic garbage collection.

Categories