我们来聊聊JVM垃圾回收

我们的对象被分配在哪里

首先来看这么一段代码:

public class Test {
    private static Teacher teacher = new Teacher();

    public static void main(String[] args) {
       load();
    }

    public static void load() {
        User user = new User();
    }
}

上面的对象分配如下
在这里插入图片描述
首先是静态类变量分配在方法区中,然后在堆新生代创建Teacher,由teacher指向
其次是在main方法中执行 load方法,在java虚拟机栈压栈,创建一个load栈帧,栈帧中包含user局部变量,同时在堆内存中创建User实例对象,由user指向User实例对象
需要注意的是基本所有的对象创建都是在新生代,除非是大对象直接进入老年代

什么时候发生GC

可以看到在load方法执行后,出栈,user变量销毁,User对象就没有有变量指向了,成了需要回收的垃圾对象。当新生代里的对象越来越多,都快满了,此时就会触发垃圾回收,把新生代没有人引用的对象给回收掉,释放内存空间。gc又分为miner gc 和 full gc,后续会详细介绍

聊聊GC收集算法

我们GC垃圾回收会如何回收呢?一般有如下几种算法

  1. 复制算法
    简单来说将新生代内存分为两块,S1快用于存放现在存活的对象,发生垃圾回收后就把S1存活的对象复制到S2,清空S1,后续新建的对象分配到S2,下次垃圾回收清空S2如此循环
    在这里插入图片描述
    这种算法的缺点很明显,假如我们给新生代1G的内存空间,那么只有512MB的内存空间是可以用的
  2. 标记清除算法
    这种算法就是我们在新生代中将存活的对象标记出来,然后直接清除,这样看好像是用到了所有内存
    在这里插入图片描述
    这样我们只需要将user对象清除就好了,但是会带来另一个问题:内存碎片,由于这些存活的对象分布不均,产生了许多内存碎片也会造成大量内存浪费

复制算法的优化

复制算法的缺点很明显,我们如何优化呢,将年轻代分为 :Eden区和Survivor区
在这里插入图片描述
… 待更新

发布了197 篇原创文章 · 获赞 172 · 访问量 26万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 护眼 设计师: 闪电赇

分享到微信朋友圈

×

扫一扫,手机浏览