JVM memory deep analysis and performance tuning

To better digest this article, it is recommended to read this blog post https://blog.csdn.net/cdaimadada/article/details/79884414 (java memory analysis)

In general, java memory is divided into heap and stack (the last article is about this), but, in fact, memory division is much more complicated than this!

Overview

For java programmers, with the help of the automatic memory management mechanism of the virtual machine, it is no longer necessary to write the paired delete/free code for each new operation, and it is not easy to cause memory leaks and memory overflow problems. The virtual machine manages the memory It seems good, but once there is a memory leak or overflow problem, if you don't understand how the virtual machine uses memory, then troubleshooting will become an extremely difficult job.


java memory partition

According to the standard, java memory can be divided into:

1. Program counter: It is a small memory space that can be regarded as a line number indicator of the bytecode executed by the current thread lock. A processor will only execute instructions in one thread. Therefore, in order to restore the correct execution position after thread switching, each thread needs to have an independent program counter, and each thread does not affect each other and is stored independently.

2. Java virtual machine stack: The Java virtual machine stack describes the memory model of java method execution: each method creates a stack frame at the same time as it is executed, which is used to store local variable tables, operand stacks, dynamic links, interfaces, etc. information. The process from invocation to completion of each method corresponds to the process of pushing a stack frame to popping out of the stack in the virtual machine stack. The local variable table is used to store various basic data types and object reference types known at compile time, and the stack memory is used to run threads.

3. Local method stack: The role played by the local method stack and the virtual machine stack is very similar, but the virtual machine stack serves the virtual machine to execute the java method, while the local method stack serves the virtual machine using the native method

4, java heap: the only purpose of the heap memory area is to store object instances

5. Method area: It is used to store class information, constants, static variables, etc. that have been loaded by the virtual machine. Although the Java Virtual Machine specification describes the method area as a logical part of the heap, it also has an alias called Non-Heap to separate it from the Java heap. Relatively speaking, garbage collection behavior is relatively rare in this area. The memory reclamation in this area is mainly aimed at the reclamation of the constant pool and the unloading of types.

5.1, runtime constant pool: it is part of the method area and is used to store various literals and symbolic references generated by the compiler (for a detailed explanation of the constant pool, please see the article I recommended above)

Among them, the method area and the heap are the memory areas shared by all threads; the virtual machine stack, the native method stack, and the program counter are the thread-private memory areas.

Someone divided java memory as follows (note: less program counter! less program counter! less program counter!)



java heap memory





Java heap memory is logically divided into three blocks: young generation, old generation and permanent generation. But in fact, it is only divided into two parts: the young generation and the old generation. Permanent generation does not belong to heap memory!

Eden is the young generation, Old is the old generation, Perm is the permanent generation, Metaspace: MetaSpace

young generation

As can be seen from the above figure, the java heap memory is divided into multiple independent modules. More broadly, java divides memory into young generation and old generation.

The young generation is where all new objects are created. Garbage collection is triggered when the young generation memory space is used up. This garbage collection is called Minor GC. The young generation is divided into three parts---Enden area and two Survivor areas

When the Eden area is filled with objects, Minor GC is also called Full GC . And transfer all surviving objects to the Survivor0 area. When the Survivor0 area is also full, the object will go to the Survivor1 area, and when the 1 area is also full, it will go to the old age area.

old generation

The old generation memory includes long-lived objects and objects that survive multiple Minor GCs

Garbage collection is usually performed when the old generation memory is full. Old age garbage collection is called Major GC. Major GC will take more time. Performing Major GC multiple times will cause an unresponsive error!

When the old age is full, an OOM exception will be reported

Stop the world event

Why is this event happening?

When a thread needs to use the object in the heap, if there is no such event, if garbage collection needs to be performed at this time, it means that there are two operations on the same object at the same time, which is obviously unreasonable!

So when the JVM is designed, when the memory is full, that is, when the garbage collection starts, the Stop the world event is triggered. It will make the application pause and garbage collect first.

The garbage collection time depends on the garbage collection policy. This is why it is necessary to monitor and tune garbage collection. This avoids timeout errors for applications that require fast responses.

permanent generation

The Permanent Generation or "Perm Gen" contains application metadata required by the JVM, which describes the classes and methods used in the application. Note that the permanent generation is not part of the Java heap memory.

The permanent generation stores classes used by the JVM at runtime. The permanent generation mainly contains the classes and methods of the Java SE library . Objects in the permanent generation are garbage collected at full GC.

method area

The method area is part of the permanent generation space and is used to store type information (runtime constants and static variables) and method code and constructor code.

jvm performance tuning

Java heap memory switch

Java provides a large number of memory switches (parameters) that we can use to set memory sizes and their ratios. Here are some commonly used switches:


There are two ways of JVM memory tuning,

The first: through the Myeclipse development tool, set the startup parameters for the jvm, you can tune

Specific operation: Windows->Preferences->installed jres->edit->Then add parameters in default VM arguements. as follows:


Setting method: Generally speaking, the size of Xms and Xmx should be the same, so as to avoid adjusting the size of the heap after GC. -XX: PermSize is the size of the permanent generation. If there are too many jar packages in a project, you can set the PermSize The setting is relatively large, after all, the permanent generation mainly stores class files .

(1). Heap memory allocation

The memory initially allocated by the JVM is specified by -Xms, and the default is 1/64 of the physical memory; the maximum allocated memory by the JVM is specified by -Xmx, and the default is 1/4 of the physical memory. When the default free heap memory is less than 40%, the JVM will increase the heap until the maximum limit of -Xmx; when the free heap memory is greater than 70%, the JVM will reduce the heap until the minimum limit of -Xms. Therefore, the server generally sets -Xms, -Xmx equal to avoid adjusting the size of the heap after each GC. You can use the -Xmn -Xms -Xmx and other options provided by the JVM to set the heap memory. Generally, the -Xms and -Xmx options should be set to the same, and -Xmn is 1/4 of the -Xmx value. The maximum value of the heap is recommended Set it to 80% of the maximum available memory. After all, memory is also needed elsewhere.

(2). Non-heap memory allocation is also called a permanently saved area, which is used to store Class and Meta information. Class is put into this area when it is loaded. It is different from the Heap area where the class instance (Instance) is stored, and the GC (Garbage Collection) will not clean up the PermGen space during the runtime of the main program. The JVM uses -XX:PermSize to set the initial value of non-heap memory, the default is 1/64 of the physical memory; the maximum non-heap memory size is set by XX:MaxPermSize, the default is 1/4 of the physical memory. The GC will not clean up the PermGen space , so if your APP loads a lot of CLASS, it is likely to have a PermGen space error (ie PerGen space out of memory exception). 

Test code: System.out.println(Runtime.getRuntime().maxMemory());

The second:


Use of JVM monitoring tools

Open Jconsole in the bin under the java installation directory, select a process related to the java program, and enter to see the current jvm memory and usage. If you find that the memory or permanent generation memory is not enough, or there are too many garbage collections, go to Tune JVM parameters to improve the performance and throughput of your application's programs.

Introduction of three kinds of memory overflow exceptions

1. OutOfMemoryError: Java heap space  堆溢出

内存溢出主要存在问题就是出现在这个情况中。当在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。一般老年区满的时候就会出现这个错误。

 2. OutOfMemoryError: PermGen space   非堆溢出(永久保存区域溢出)

这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。

3. OutOfMemoryError: unable to create new native thread.   无法创建新的线程

这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。


Java垃圾回收调优应该是提升应用吞吐量的最后一个选择。当你发现应用由于长时间垃圾回收导致应用性能下降、出现超时的时候,应该考虑java垃圾收集调优。

如果在日志里看到java.lang.OutOfMemoryError:PermGen space错误,那么可以尝试使用 -XX:PermGen 和-XX:MaxPermGen JVM选线去监控并增加Perm Gen内存空间。你也可以尝试使用-XX:+CMSClassUploadingEnabled并查看使用CMS垃圾收集器的执行性能。

如果你看到了大量的Full GC操作,那么你也应该尝试增大老年代的内存空间。

链接:

Tomcat中JVM内存溢出及合理配置及maxThreads如何配置:https://www.cnblogs.com/hadoop-dev/p/6006970.html

Java内存与垃圾回收调优:http://www.importnew.com/14086.html

教学视频:
https://ke.qq.com/webcourse/index.html#course_id=237614&term_id=100280262&taid=1626139043012654&vid=d14207bcmjx

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325680369&siteId=291194637