JVM----内存模型
-XX:+PrintGCDetails:程序运行的时候打印堆的大小。如果发生GC,会打印GC日志
-Xss:设置的大小是一个线程开辟的空间,设置的越大,系统可开辟的线程数量越少,默认是1M
-Xms:堆最小空间
-Xmx:堆最大空间
-Xmn:年轻代
-XX:MetaspaceSize:方法区(jdk1.8)
-XX:MaxMetaspaceSize
-XX:PretenureSizeThreshold=1024*1024*10 -XX:+UseSerialGC 大于10M的对象会直接放到年老代
SpringBoot程序JVM参数设置格式(Tomcat启动直接加在bin目录下catalina.sh文件里)
java -Xms2048M -Xmx2048M -Xmn1024M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M -jar xx.jar
如何设置
根据每秒处理请求数量✖️产生对象大小,设置成年轻代大小
年轻代设置过小,在高并发的情况下,很频繁发生minor GC,有些请求对象还没有结束,经过频繁GC之后,容易将这些垃圾对象放到老年代。
JVM虚拟机
栈
栈:最重要就是栈帧
栈帧,每一个方法都会开辟一个栈帧,栈帧包括局部变量表,操作数栈,动态链接,方法出口。
堆
在堆中的对象,每个对象头,保存指向方法区中类元数据的指针。
方法区
方法区中类元数据中的静态变量对象指向堆。
方法区是一个概念,实现方式在jdk 1.8之前是持久带,1.8之后是元空间
直接引用和符号引用
像class,方法名字,方法变量,‘computer’,‘()’,这些都是符号都是一个符号,这些符号保存在常量池中。
new Math()
math.computer();
当我们调用math.computer(),computer(),是组合的符号,此时进行动态链接,将computer(),符号引用变成直接引用,保存在栈帧中的动态链接中。
直接引用指向 方法区保存着computer指令码 的入口
逃逸分析
JVM运行的模式:解释,编译,混合(JVM采用),如果全部吧代码翻译成机器吗,机器码的代码量多,如果全部加载到内存,会占用大量内存。
在编辑过程中,jvm对我们代码进行优化,比如对象逃逸分析等。
jdk1.7之后默认开启逃逸分析,逃逸分析本质就是对象创建在栈内存中,方法结束,对象立即回收,那么什么样的对象应该放到栈中呢,就是方法中创建的对象没有逃出该方法。例如
public class Test{ //该方法中的user对象逃出了方法; public User A(){ User user = new User(); return user; } //该方法中的user对象没有逃出方法; public void B(){ User user = new User(); } }