JVM学习二 垃圾收集器与内存分配策略

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Jon_jing/article/details/90698972

一 如何判断无效对象需要回收

1.引用计数法:每一个对象都有一个计数器,当这个对象被一个变量或者另一个对象引用一次,计数器加一,若引用失效,计数器减一,如果计数器为0则认为该对象为无效对象(无法识别对象循环引用)

2.可达性分析法:所有和GC Root直接或间接关联的对象都是有效对象,和GC Root没有关联的对象就是无效对象

GC Root是指

a.java虚拟机栈所引用的对象(栈帧中局部变量表中引用类型的变量所引用的对象)

b.方法区中静态属性引用的对象

c.方法区中常量所引用的对象

d.本地方法栈所引用的对象

3.引用扩充

          强引用:类似于Object obj = new Object(),只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象

          软引用:用来描述一些还有用但是非必需的对象在系统将要发生内存溢出一场之前,将会把这些对象列进回收范围之内进行第二次回收,如果这次回收还没有足够的内存,会抛出内存溢出异常

           弱引用:也是用来描述非必须对象的,但是他的强度比软引用还要弱一些,被弱引用关联的对象只能生存到下一次垃圾收集收集之前,当垃圾收集器工作时,无论当时内存是否足够,都会回收掉只被弱引用关联的对象

            虚引用也成为幽灵引用或者幻影引用,他是最弱的引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例,为一个对象设置虚引用关联的唯一目的是能在这个对象被收集器回收的时收到一个系统通知

4.回收方法区

回收方法区主要有两个:废弃常量和无用类

回收废弃常量:假设系统有个常量“a”,当没有任何String对象引用这个常量池中的“a”,这个“a”就被从常量池清除

无用类的满足条件:该类的所有实例都已经被回收,也就是java堆中不存在该类的任何实例

                                 加载该类的ClassLoader已经被回收

                                 该类对应的java.lang.class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法

二 垃圾收集算法

1.安全点:在特定的位置几率了OopMap的信息

2.跑到安全点上再停顿的方法

抢先式中断:不需要线程执行代码的主动配合,在GC发生时,首先把所有的线程全部中断,如果线程中断的地方不在安全点上就恢复线程,跑到安全点上(几乎不使用)

主动式中断:GC需要中短线程的时候,不需要对线程操作,仅仅简单的设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标志为真时就自己中断挂起,轮训标志的地方和安全点是重合的,另外再加上创建对象需要分配内存的地方

3.安全区域:指一段代码片段中,引用关系不会发生改变,在这个区域中的任意地方开始GC都是安全的

三 内存分配回收策略

对象内存分配,大方向讲式子堆上分配(但也可能经过JIT编译后被拆散为标量类型并间接地栈上分配),对象主要分配在新生代的Eden区,如果启动了本地线程分配缓冲,将按线程有限在TLAB上分配,少数情况直接分配在老年代

分配规则并不是百分百固定的,其细节取决于当前使用的哪一种垃圾收集器组合,还有虚拟机中与内存相关的参数的设置

内存分配规则:对象悠闲在Eden分配

                          大对象直接进入老年代

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

                            动态对象年龄判定

猜你喜欢

转载自blog.csdn.net/Jon_jing/article/details/90698972
今日推荐