JVM垃圾回收机制

聊到垃圾回收机制:就有必要说下为什么要进行垃圾回收,我们在项目中创建的对象都是在对空间分配内存的。如果程序运行的过程中,已经使用完毕的对象不会在接下来的程序中再使用,那么这块空间就肯定需要释放,不然就会发生内存溢出的异常。因此就需要垃圾回收。

内存溢出和内存泄漏的区别
内存溢出:需要4g内存,但是只支持3g内存,溢出
内存泄漏:定义很多静态变量 垃圾是不会回收的。这个对象没有被引用,再次申请会出现内存泄漏。
刚开始分配的对象是放在eden区。 新生代中eden和s0和s1的比值大概是8:1:1 ,当然这个比值是可以修改的。
垃圾回收机制 就是不定时的向堆内存中清理不可达对象。
常用的垃圾回收算法

  1. 引用计数法
    思想:每次创建的对象在堆空间内有15次机会,如果后台的gc线程在一段时间后会访问堆空间存储的对象,如果发现没有被引用则将机会标记减1,如果发现有被引用就加1,如此循环直到标记为0则垃圾回收机制会回收该空间。
    缺点:无法检测出循环引用。
    JVM垃圾回收机制

  2. 标记清除 --> 发生在老年代
    它会给对象设置一个标志 0代表可达,1代表不可以,当gc线程多次扫描发现对象对此没有被引用时会将标识标为1,标记该对象为垃圾。没有连续删除
    举例说明:商品架上的商品,售货员检测一行的商品时,发现商品有缺陷,就拿下来直到一行商品都检测完整。这样检测完毕之后,一行的商品会比较凌乱。看着不齐。
    JVM垃圾回收机制

  3. 标记压缩/标记整理
    标记整理:调用gc线程进行垃圾回收的时候。如果发现有对象多次没有被引用就标记为1,而且向一端偏移到,然后清除边界意外的内存,可以看到标记存活的对象将被整理,按照内存地址依次排列而被标记为1的就会被清除。

JVM垃圾回收机制
4. 复制算法 发生在新生代
复制算法发生在s0 和s1区, 加入刚开始存放的对象a,b都是在s0区,gc线程在经过检测的过程中,发现s0中的a已经经常不被使用了,那么gc只会将b复制到s1区,然后将s0区所有已经经常不被使用的对象清除。然后下次gc会检测s1区,将s1区中经常使用的放到s0区,然后清除s1区,如此循环。

  1. 分代算法
    所谓的分代算法就是在不同的代采用不同的算法。