1.jvm运行时区域划分
线程私有
程序计数器:线程执行到那一行
虚拟机栈:java方法内存模型
本地方法栈:native方法内存模型
在Hotspot中JVM中本地方法和虚拟机栈合二为一
线程共享
堆:所有对象实例与数组对象
方法区:已加载的类信息、静态变量、常量
运行时常量池:方法区的一部分,字面量与符号引用
字面量:直接写出来的值 10、“abc” 10.1
2.GC相关:
如何判断对象是否存活
引用计数法:无法解决循环引用问题(我中有你,你中有我)
导致无用对象仍然判断存活而无法被回收
可达性分析算法:
哪些对象可以作为GC Roots:栈中引用的对象;类中静态变量、常量引用的对象
面试题JDK1.2关于引用的扩充
强引用:程序普遍存在的,类似于直接new称为强引用。只要对象被任意一个强引用指向,即便抛出OOM异常,也无法回收被强引用指向的对象。
软引用:描述有用但不必须对象,SoftReference类描述软引用。若对象只被软引用指向,当前内存够用时,不回收,当即将抛出OOM异常,一次性回收所有仅被软引用指向的对象
弱引用:WeakReference 仅被弱引用指向的对象,无论内存是否够用,当GC开始时,都会回收掉仅被软引用指向的对象
虚引用:PhantomReference
虚引用完全不对对象的生存周期产生任何影响,也无法通过虚引用取得一个对象实例。
当虚引用指向的对象被GC时,JVM会发回一个回收通知。
对象的自我拯救finalize JDK1.9 @Deprecated
-若对象所在的类覆写了finalize()
-该对象的finalize()未被JVM调用过,JVM会调用此对象的finalize()
-该对象的finalize()被JVM调用过,此对象被标记为不再存活,可以进行GC
-对象所在的类没有覆写finalize(),此对象直接标记为不再存活,可以进行GC
final、finally、finalize
垃圾回收算法
将堆空间分为新生代和老年代,默认对象在新生代中产生,新生代对象“朝生夕死”。新生代对象的存活率极低(<=2%)
Java采用分代回收算法,其中新生代采用复制算法,老年代采用标记算法-整理算法
-Xss 设置栈的大小
-Xms设置堆的最小值
-Xmx设置堆得到最大值
-Xmn设置新生代内存大小
新生代的复制算法执行步骤:
新生代的GC比老年代的GC速度快上10倍,发生频率高的多
为什么老年代不采用复制算法?
因为老年代对象存活率极高,若采用复制算法,复制开销远高于新生代,不适合复制算法