JVM的内存结构:
分为五个结构:
1.程序计数器:
当前线程所执行的字节码的行号指示器。各线程计数器相互独立,称为“线程私有”的内存区域。
2.Java虚拟机栈:
用于描述Java方法的内存模型。每个方法执行时都会创建一个栈帧用于存储信息,包括局部变量表,操作数栈,动态链接,方法出口。每个方法从调用到执行完成的过程就对应着一个栈帧在虚拟机中从入栈到住栈的过程。(StackOverflowError/OutofMemoryError)
3.本地方法栈:
用为Native方法服务。基本同↑。
4.Java堆:
所有现存共享的一块区域,唯一作用是存放对象实例。GC“堆”:新生代./老年代
5.方法区:
各个线程共享区域,同↑。存储堆中类似数据,是堆的一个逻辑部分。(OutofMemoryError)
GC回收
关于垃圾收集的思考:what/when/how
what:
内存中已经不再被使用到的内存空间就是垃圾。(Java中的四种引用)
how:
引用计数法
对象被引用时计数器值+1;引用失效时计数器值-1。难以解决对象之间相互循环引用的问题(对象AB相互引用,引用计数互不为0,无法回收)。
可达性分析
以GC Roots为起始点向下搜索,搜索路径称为引用链。当一个对象没有任何引用链相连则不可达,即该对象不可用,所以会被判定为可回收对象。
可作为GC Roots的对象:虚拟机栈中引用对象/方法区静态属性,常量引用对象/Native方法引用对象。
when:
引用计数法:当对象变成垃圾后,程序可以立刻感知,马上回收。 可达性分析:回收不及时,直到执行 GC 才能感知垃圾对象。