1.引用计数法
当对象被创建出来时,会给该对象赋值一个变量为1,当有其他对象引用改对象时,就对变量+1,当改对象的生命周期结束或者赋值其他值后,对变量-1,当变量为0时,GC回收该对象
如果互相引用的话,则变量永远不为0,则GC不回收。
2.可达性算法
从GCRoot开始扫描,扫描所有引用节点,扫描完,没有被引用到的节点就是需要回收的
可作为GCRoot的对象
1).栈中的引用对象
2).方法区中的类静态属性引用的对象
3).方法区常量引用的对象
4).本地方法栈中的静态方法引用对象
3.标记-清除算法
两步:标记需要回收的对象,清除标记的对象
从GCRoot开始标记需要回收的对象,在全盘扫描被标记的对象,直接垃圾回收
缺点:垃圾回收之后会存在对个内存碎片,如果有大对象创建的话,可能会因内存不足,触发一次垃圾回收
4.复制算法
将推分成对象面和多个空闲面,程序从对象面为对象分配空间,当对象面满了,则开始从GCRoot扫描存活的对象,复制到空闲面,对原对象面回收,这样空闲面变成了对象面,原对象面变成了空闲面
5.标记-整理算法
两步:标记需要回收的对象,然后将标记的对象向最右端移动,然后清除边缘对象
延伸:
如何判断大对象:
可通过参数指定对象超过多少直接进入老年代 -XX:PretenureSizeThreshold=1M
新生代和老年代的区别:
所谓的新生代和老年代是针对于分代收集算法来定义的,新生代又分为Eden和Survivor两个区,加上老年代就这三个区。
数据会首先分配到Eden区当中(当然也有特殊情况,如果是大对象那么会直接放入到老年代(大对象是指需要大量连续内存空间的java对象))
当Eden没有足够空间的时候就会 触发jvm发起一次Minor GC。
如果对象经过一次Minor GC还存活,并且又能被Survivor空间接受,那么将被移动到Survivor空 间当中。并将其年龄设为1,对象在Survivor每熬过一次Minor GC,年龄就加1,当年龄达到一定的程度(默认为15)时,就会被晋升到老年代 中了,当然晋升老年代的年龄是可以设置的。如果老年代满了就执行:Full GC 因为不经常执行,因此采用了 Mark-Compact算法清理