JVM内存模型
约 705 字大约 2 分钟
2025-09-24
堆里存放对象new出来的值, 方法区里存的是new出来的值在堆里的地址;
方法区:存放常量、静态变量、类信息;
堆和方法区是所有线程共享的;
栈、本地方法栈、程序计数器是每个线程独有的;
堆
分为年轻代和老年代
年轻代占1/3,老年代占2/3
年轻代:Eden区(8/10)和Survivor区(两个1/10)
new一个对象,对象会放到Eden区里,如果Eden区放满了,那么字节码执行引擎会建一个minor gc垃圾回收的线程,去判断将对象里没有引用其他的无用对象给清理掉,对象里有引用其他对象的会直接复制到Survivor区;(栈里面找局部变量,方法区里找静态变量,这些就是gc root,从这些变量开始找这些变量所指向的堆里的对象有没有成员变量引用其他对象,如果有则复制到Survivor区,没有则删除)
当Eden区又满了之后,这次会清理Eden区和两Survivor区中有存对象的区,gc会将Eden区和有存对象的一个Survivor区里无用的对象清理掉,有用的对象则会移到另一个此时还没有存对象的Survivor区;
分代年龄:每经历一次gc回收,没有被回收的对象的分代年龄就会加1,一般情况下分代年龄达到15就会转移到老年代;
当老年代区域也放满之后,会先触发full gc,full gc与minor gc类似,但是full gc是回收整个堆空间和方法区;如果此时老年代区域还是满的,则会触发OOM,报内存溢出异常;
STW(stop the world):minor gc和full gc都可能会触发STW机制,STW会停止所有的用户线程,gc等是后台线程;(用户会感觉到网站卡了一下);
JVM调优的目的是减少full gc和一次full gc的执行时间(因为full gc执行一次的时间相对来说比较长,所以STW的时间也会比较长);minor gc的执行时间几乎不会有影响,所以执行STW也不会有影响;
JVM为什么要设计STW机制?
防止在进行GC的过程中,已经找到了一部分的有用对象,但是这个对象所属的线程执行完了,栈内存空间被释放了,意味着原先找出来的有用对象在GC还没有结束的时候变成了垃圾对象,意味着之前的GC分辨对象有用无用的操作白做了,所以干脆直接暂停了所有线程;
