垃圾回收机制
不定时的回收不可达的对象。
什么是不可达对象
没有被使用的对象。
怎么判断对象是否可达
1、引用计数算法
大概的意思就是对象被引用一次加一,取消引用一次减一。但是有一个致命的缺点就是对象互相引用。所以该算法jvm不使用。
2、可达性算法
通过一些系列GCROOT作为根节点,当一个对象跟根节点没有任何相连时,则认为该对象为垃圾对象。
什么才能做为GCROOT
可以这样想就知道,堆中数据是共享数据,那么谁来使用共享数据,谁就是GCROOT。
如:
- 虚拟机栈中的局部变量表。如:
void methoda() {
Object object = new Object();
}
- 方法区
如:
private static ClassA = ClassA.getInstance();
- 本地方法栈
void methoda() {
Object object = new Object();
}
怎么回收不可达对象,也就是垃圾对象
通过垃圾回收算法进行回收
- 标记-清除
描述:先标记出需要回收的对象,标记完成后进行清除。
缺点:清除之后,没有做碎片整理,会导致需要大内存的对象无法存储。如:堆内存零碎空间加起来还有10M,正好新对象所需的内存空间也是10M,但是他放不进去,因为没有一个完整的空间容纳。 - 标记-整理
对标记-删除算法一种优化,也就是删除之后,还能帮我做碎片整理。
缺点:碎片整理复杂。
适用场景:老年代。 - 复制
可以说是对标记-整理进行了优化,因为不用考虑整理碎片整理问题,但是它是以牺牲空间为代价。
描述:内存一分为二(使用区和未使用区),首先标记出需要回收的对象,然后将不需要回收的对象未使用区,接着将之前的使用区全部清空,变成了未使用区。
缺点:如果可用的对象很多,复制会消耗性能。
适用场景:可用对象不是很多时。如:新生代
新生代和老年代概念是从分代收集提出的,分代收集是针对着垃圾回收特点不同,将Java堆分为新生代和老年代,新生代采用复制算法,老年代采用标记-整理或标记-删除
新生代工作流程
第一个minor gc流程
Eden满时,发生一次minor gc,将存活的对象移动到from区。
第二次minor gc流程
Eden满时,发生一次minor gc,将Eden和from区存活对象移动到to区,清除Eden和from区。
第三次minor gc流程
Eden满时,发生一次minor gc,将Eden和to区存活对象移动到from区,清除Eden和to区。
标记-清除、标准-整理、复制算法实现,也就是垃圾回收器
类加载机制
什么是类加载机制
虚拟机把class文件加载到内存,并对数据进行验证、准备、解析和初始化,最终转换到虚拟机直接能使用的java类型。
初始化时机
1、new时
2、反射时
类加载器
从jvm来讲,分为两种,一种是bootstarpclassloader启动类加载器,所有其他的类加载器。
从java开发者角度来讲,分为四种,bootstrapclassloader启动类加载器、扩展类加载器、系统加载器和自定义加载器
JVM默认使用双亲委派类加载机制,意思是说先加载父类在加载子类
双亲委托模型机制
一个类加载器收到加载类请求时,它不会尝试去加载类,而是委托给其父类加载器去完成,但父类加载器不能完成这个加载请求时,子类加载器才会尝试去加载。
运行时数据区
程序计数器
简单理解,就是一个程序执行顺序的标记。
虚拟机栈
虚拟机栈是线程私有的,每个方法在执行时,都会创建一个栈帧存放到虚拟机栈中,执行完毕后,从虚拟机栈中移出。创建栈帧的目的是为了存放局部变量表、操作数栈和动态链接。
堆
堆是共享数据区,用于存放对象实例和数组。
方法区
方法区是共享数据区,用户存放类信息,常量,静态变量,静态方法。