面试整理
JVM (Java Virtual Machine)
Runtime Data Area
线程共享区
方法区/永久代/持久代/元空间 存有静态变量+常量+类信息+运行时的常量池
堆 存对象
- 新生代(Eden)1/3
survior [From | To] 当 age == 15[为什么是15? 因为对象头中age占4位] 之后, 由新生代转为老年代
- 老年代 2/3
线程私有区
包含本地方法栈 虚拟机栈 程序计数区
虚拟机栈(Stack) 一个线程有多个method,对应有多个栈帧,生命周期等同与线程
栈帧
- 局部变量表(local variable)用来存储局部变量
- 操作数栈 存储在操作数栈的变量用完会被回收,所以需要局部变量表来存储。
- 动态链接 在程序运行期间,由符号引用**转化【加载class,将class实例化成一个对象】**为直接引用
~~对应静态链接 在程序解析期间,由符号引用转化为直接引用~~
符号引用 例如,com/hetun/Demo.math: ()I
直接引用 局部变量里的reference指向堆
程序计数区(Program Counter Register)指针,指向下一条指令的地址
本地方法栈 (Native Method Stack)我的理解是将Stack里存储的变量load到native method stack 后统一交由cpu计算得到的值再存回给stack
GC 垃圾回收作用在堆上
什么可以被回收?
- 如何判断一个object是否可以被回收
M1: 引用计数法 利用对象头里的引用计数器,当 == 0时,表明可被回收
优点:效率高
缺点:无法解决循环引用
M2:可达性分析法 引用链的模式,到GC root没有任何引用链相连,则证明改对象可以被回收了
- 如何判断一个常量是否可以被回收
如果没有任何一个reference指向改常量,则代表可以被回收
- 如何判断一个类是否可以被回收
1. 该类的所有实例都被回收
2. 加载该类的classlaoder被回收(难以达到)
3. 该类对应的对象没有在任何引用
如何回收?
- 标记清除法
缺点:逻辑地址不连续,标记和清除效率低
空间:会产生碎片
- 复制算法 一半留空会用存存活的东西【survivor】
缺点: 内存没有完全被利用
- 标记整理算法 将可回收的回收后,把剩余的存活对象进行整理,保证内存空间是连续的
- 分代收集算法 新生代用复制算法,老年代用标记清除/标记整理