11 Eylül 2022 Pazar

java komutu Native Memory Seçenekleri

Giriş
1. Uygulama -XX:NativeMemoryTracking=... şeklinde çalıştırılır
2. Uygulamaya jcmd ile Diagnostic Command Request gönderilir ve bir çıktı alınır

Native Memory allocations through JNI - Yani native Anahtar Kelimesi
Açıklaması şöyle. "Native memory" alanına erişmek yani C kodunu çağırmak için Java'daki native anahtar kelimesi kullanılır.
Native memory is memory allocated by the OS on behalf of the Java process through C code. This C code is called by native methods in certain Java classes.
Mesela java.util.zip paketindeki bazı kodlar şöyle
private static native void initIDs();
private native static long init(int level, int strategy, boolean nowrap);
private native static void setDictionary(long addr, byte[] b, int off, int len);
private native int deflateBytes(long addr, byte[] b, int off, int len,
                                  int flush);
private native static int getAdler(long addr);
private native static void reset(long addr);
private native static void end(long addr);
Neden Native Anahtar Kelimesi
Açıklaması şöyle. Sebep performans
The final possibility of native memory allocation from the JVM comes from libraries backed by native code. In some cases it makes more sense to implement functionality as native code, generated by compilers for languages such as C, C++ or Rust. Native code can perform better, or it might be the only way to access certain OS level functionality. Java allows calling native code through the Java Native Interface (JNI). Code called through JNI manages its own memory, so this memory is not tracked by the JVM and not automatically cleaned up through garbage collection. In a language like C, memory is managed by calling the malloc and free functions, which respectively request memory from and return memory to the OS. This is far from the complete picture, but more on that in the next level.
Native Memory Kategorileri
Açıklaması şöyle
Native memory consists of several native memory categories, such as: java heap, metaspace, thread etc.

The next table taken from Oracle’s site describes native memory categories used by NMT. Take into consideration that these categories may change with a release:
Şeklen şöyle

XX:NativeMemoryTracking seçeneği
Açıklaması şöyle. Bu seçeneği kullanınca JVM Off-heap kaynaklarını da takip etmeye başlar.
There are a few categories of native memory that the JVM can track by default, such as memory used by the garbage collector, thread stacks, loaded classes, and more. To enable JVM native memory tracking we simply pass it the -XX:NativeMemoryTracking=detail flag,
-XX:NativeMemoryTracking=... ile kullanılabilecek seçenekler şöyle
1. summary
2. detail
Örnek
Şöyle yaparız
java -XX:NativeMemoryTracking=detail -jar YourApp.jar
Örnek
Eğer testlerde kullanmak istersek şöyle yaparız
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <argLine>-XX:NativeMemoryTracking=detail</argLine>
      </configuration>
    </plugin>
  </plugins>
</build>
Açıklaması şöyle
Pay attention: Enabling NMT will result in a 5–10 percent JVM performance drop. By the way, NMT usage is also tracked by NMT.

NMT is not enabled by default. To enable this feature we need to add the following argument to the application’s JVM parameters: -XX:NativeMemoryTracking=summary

(to get a more detailed view of native memory usage, use: -XX:NativeMemoryTracking=detail)

To obtain the NMT details once the feature is enabled you should perform the following command:

jcmd <pid> VM.native_memory summary
‘<pid>’ is the PID of the application being analyzed

I ran this command manually several times and noticed a native memory category which was leaking, it was “serviceability”. After some research it was found out that there was a bug in 17.0.1 related to ThreadMXBean#dumpAllThreads method. Our application used that method. To fix the problem, I made some changes to avoid using that method (also found out that this bug was known and would be fixed in 17.0.2). After redeploying the fix and checking memory consumption, I was content, the issue disappeared.


Hiç yorum yok:

Yorum Gönder