29 Ocak 2019 Salı

Metaspace - Dynamic Code Generation İçin de Kullanılır

Giriş
Java 8'den itibaren PermGen yerine Metaspace kullanılmaya başladı. Açıklaması şöyle.
Class metadata is allocated in native memory(referred as metaspace)
PermGen Space
Açıklaması şöyle
... this was common in older JVMs, especially with tools that do heavy bytecode manipulation. It isn't as common today thanks to dynamic PermGen space
MetaSpace Heap İçinde Değildir
Açıklaması şöyle.
The key difference between PermGen and Metaspace is this: while PermGen is part of Java Heap (Maximum size configured by -Xmx option), Metaspace is NOT part of Heap. Rather Metaspace is part of Native Memory (process memory) which is only limited by the Host Operating System.

Üst Sınır Vermek
-XX:MaxMetaSpaceSize ile kontrol edilir. Açıklaması şöyle.
In short, Metaspace size auto increases in native memory as required to load class metadata if not restricted with -XX:MaxMetaspaceSize
MetaSpace Biterse
Eğer meta space biterse OutOfMemoryError fırlatılır. Yani OutOfMemoryError sadece heap bittiği için fırlatılmaz. Bu durumda hata şöyledir. En sondaki Metaspace kelimesine dikkat.
java.lang.OutOfMemoryError: Metaspace
Açıklaması şöyle
When you encounter java.lang.OutOfMemoryError: Metaspace, it indicates that the Metaspace region in the JVM memory is getting saturated. Metaspace is the region where metadata details that are required to execute your application are stored. In a nutshell, it contains class definitions, method definitions, and other metadata of your application. 
Örnek
Buradaki şekilde heap'te halen çok fazla yer olmasına rağmen çok fazla "Full Garbage Collection" olduğu görülebilir

Metaspace ise şöyledir. Yani doludur ve Full GC'ye sebep olmaktadır

Örnek
Şöyle yaparız
//JVM Options: -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
//Dynamically create objects with Spring’s GCLib
public class MetaspaceOOMDemo {
  public static void main(String[] args) {
    while (true) {
      Enhancer enhancer = new Enhancer();
      enhancer.setSuperclass(MetaspaceOOMDemo.class);
      enhancer.setUseCache(false);
      enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
        return methodProxy.invokeSuper(o, objects);
      });
      enhancer.create();
    }
  }
}
Açıklaması şöyle
Method area overflow is also a common memory overflow exception. In application scenarios where a large number of dynamic classes are generated during frequent runtime, special attention should be paid to the recycling of these classes. In addition to the above GCLib bytecode enhancement and dynamic language, such scenarios are also common, such as a large number of JSP or applications that dynamically generate JSP files (there may be in the traditional software industry in ancient times), OSGi-based applications (even if the same class files, loaded by different loaders will also be treated as different classes), etc.

The method area is generally not easy to generate in JDK8. HotSpot provides some parameters to set the meta space, which can play a preventive role.

-XX:MaxMetaspaceSizeSet the maximum value of the meta space, the default is -1, which means no limit (it is still limited by the size of the local memory)
-XX:MetaspaceSizeSpecify the initial space size of the meta space, in bytes, reaching this value will trigger GC to perform type unloading, and the collector will adjust the value at the same time
-XX:MinMetaspaceFreeRatioControlling the minimum percentage of metaspace remaining capacity after GC can reduce the frequency of garbage collection due to insufficient metaspace, and similarlyMaxMetaspaceFreeRatio

Metaspace Hatalarını Bulmak
1. Java 8
Şöyle yaparız
java {app_name} -verbose:class
2. Java 9 
Şöyle yaparız
java {app_name} -Xlog:class+load=info:/opt/log/loadedClasses.txt
3. jcmd komutu kullanılabilir
Şöyle yaparız
# Ekrana
jcmd {pid} GC.class_histogram

# Dosyaya
jcmd {pid} GC.class_histogram filename={file-path}
4. Guava kullanılabilir
Şöyle yaparız

5. Heap Dump Analysis Yapılabilir
Şöyle yaparız




Hiç yorum yok:

Yorum Gönder