如何理解Java jvm垃圾回收

发布时间:2021-10-26 14:34:24 作者:iii
来源:亿速云 阅读:107

这篇文章主要讲解了“如何理解Java jvm垃圾回收”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解Java jvm垃圾回收”吧!

常见面试题

如何理解Java jvm垃圾回收

1.JVM内存回收和分配

1.1主要的区域?

阈值的计算

如果某个年龄段的大小大于幸存区的一半,那么就取阈值或者是这个年龄最小的那个作为新的阈值升级到老年代

gc测试

场景就是先给eden分配足量的空间,然后再申请大量空间,问题就是幸存区的空间不够用

public class GCTest {
    public static void main(String[] args) {
        byte[] allocation1, allocation2;
        allocation1 = new byte[50900*1024];
        allocation2 = new byte[9500*1024];
    }
}

如何理解Java jvm垃圾回收

1.2大对象进入老年代

1.3长期存活的对象进入老年代

uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
    //survivor_capacity是survivor空间的大小
    size_t desired_survivor_size = (size_t)((((double)survivor_capacity)*TargetSurvivorRatio)/100);
    size_t total = 0;
    uint age = 1;
    while (age < table_size) {
        //sizes数组是每个年龄段对象大小
        total += sizes[age];
        if (total > desired_survivor_size) {
            break;
        }
        age++;
    }
    uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
    ...
}

1.4主要进行gc的区域

gc的类型

Young Gc:收集新生代的

Old Gc:只收集老年代的

Mixed Gc:新生代和部分老年代

Young Gc
Full Gc

1.5空间分配担保?

2.对象已经死亡?

如何理解Java jvm垃圾回收

2.1引用计数法

2.2可达性分析

gc Roots的对象

如何理解Java jvm垃圾回收

2.3再谈引用

虚引用、软引用、弱引用的区别?

2.4不可达对象不一定回收

2.5如何判断一个常量是废弃常量?

2.6如果判断一个类没有用?

3.垃圾回收算法

hotspot为什么要区分老年代和新生代?

原因就是不同的存活对象需要不同的垃圾回收算法

跨代收集假说?

如果老年代和新生代互相引用,新生代的年龄就会被拉长。但是为了知道新生代什么时候被gc,这个时候可以给新生代加上一个记忆集(把老年代划分为很多个格子,代表谁引用了我),避免扫描整个老年代

4.垃圾回收器

4.1Serial收集器

4.2ParNew收集器

4.3Parallel Scavenge收集器

4.4SerialOld

4.5Parallel Old收集器

4.6CMS收集器

问题?

内存碎片多对cpu资源敏感

如何理解Java jvm垃圾回收

4.7G1收集器

同时满足响应快处理多的问题

特点

如何理解Java jvm垃圾回收

补充字符串池的本质

第一个问题是String a="a"的时候做了什么?
第二个问题new String(“a”)发生了什么?
第三个问题intern的原理?

String s1=new String(“a”)

String s2=s1.intern();

很明显s1不等于s2如果上面的问题都清晰知道。s1引用的是堆,而s2引用的是常量池的

第四个问题

String s3=new String(“1”)+new String(“1”);

String s5=s3.intern();

String s4=“11”

那么地方他们相等吗?当然是相等的,s3会把1存入常量池,但是不会吧11存入常量池因为,还没编译出来。调用了intern之后才会把对象存入常量池,而这个时候存入的对象就是s3指向的那个。所以s4指向的也是s3的。如果是s0="11"的话那就不一样了,s3.intern只会返回常量池的对象引用地址,而不是s3的,因为s3是不能重复intern 11进去的。jdk1.6的话那么无论怎么样都是错的,intern是复制一份,而不是把对象存入常量池(因为字符串常量池在方法区,而jdk1.7它在堆所以可以很好的保存s3的引用)

下面的代码正确分析应该是三个true,但是在test里面就会先缓存了11导致false, true,false的问题。

@Test
public void test4(){
    String s3 = new String("1") + new String("1");
    String s5 = s3.intern();
    String s4 = "11";
    System.out.println(s5 == s3);
    System.out.println(s5 == s4);
    System.out.println(s3 == s4);
    System.out.println("======================");
    String s6 = new String("go") +new String("od");
    String s7 = s6.intern();
    String s8 = "good";
    System.out.println(s6 == s7);
    System.out.println(s7 == s8);
    System.out.println(s6 == s8);
}

finalize的原理

public class GCTest {
    static GCTest test;
    public void isAlive(){
        System.out.println("我还活着");
    }
    @Override
    protected void finalize() throws Throwable {
        System.out.println("我要死了");
        test=this;
    }
    public static void main(String[] args) throws InterruptedException {
       test = new GCTest();
        test=null;
        System.gc();
        Thread.sleep(500);
        if(test!=null){
            test.isAlive();
        }else{
            System.out.println("死了");
        }
        test=null;
        System.gc();
        if(test!=null){
            test.isAlive();
        }else{
            System.out.println("死了");
        }
    }
}

感谢各位的阅读,以上就是“如何理解Java jvm垃圾回收”的内容了,经过本文的学习后,相信大家对如何理解Java jvm垃圾回收这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. 如何理解JAVA中的GC
  2. Java虚拟机的Heap怎么理解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java jvm

上一篇:ceph中如何删除和添加osd节点

下一篇:如何用自定义函数进行Python发送电子邮件

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》