gc原理以及gc日志剖析

LogicStellarStriderMaster
• 阅读 1055

gc原理以及gc日志

一.概述

学习Java的我们都知道垃圾收集(gc),大部分人把这项技术当作是java语言的伴生产物。事实上,gc的历史比Java久远,1960年诞生于MIT的Lisp是第一门真正使用内存动态分配和垃圾收集技术的语言。那我们今天就研究下垃圾收集原理。

二.对象已死吗?

Java的垃圾回收主要是对推内存的回收,里面存放着Java几乎所有的对象实例,垃圾回收之前是要确定哪些还“存活”哪些已经“死去”。

1.引用计数器法

给对象添加一个引用计数器,每当有地方对他进行引用时计数器值➕1;当引用失效时,计数器值就➖1,任何时候计数器值为0的时候表示对象不可能在使用的。

2.可达性分析算法

通过一系列称为“GC Roots”的对象作为起点,从这些节点往下搜索,搜索所走过的路径称为“引用链”,当一个对象到“GC Roots”没有任何引用链相连时,则证明对象不可用的

代码示例:

gc原理以及gc日志剖析

gc日志如下:

gc原理以及gc日志剖析

我们很明显的看到gc日志中6092K->456K,意味着虚拟机并没有因为这两个对象互相引用而不回收他们,所以java虚拟机使用的是可达性分析算法标记的。

其实即使被可达性分析算法标记的不可达对象也不是一定会被回收的,虚拟机会对这些对象进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()已经被虚拟机调用过,虚拟机将这两种情况视为“没有必要执行”。如果对象被判定有必要执行finalize()方法是并在finalize()中与“GC Roots”建立关联则次对象不会被回收了。

三.垃圾回收算法

我们知道了虚拟机怎么标记一个对象是否可用,那他怎么进行回收的呢?其实堆内存可以分为新生代和老年代,新生代又被划分为一个Eden和两个Survivor区域他们的比例为8:1:1,不同的垃圾收集器厂商给对这两个区域给出了不同的算法。

1.新生代——复制算法

新生代对象的特点就是,大部门对象在一次GC中会被回收掉,所以使用的是复制算法:新生代每次创建对象的时候只会使用一个Eden和其中的一块Survivor,在垃圾回收时将存活的对象复制到另外一块Survivor区域,最后清理掉Eden和刚才的Survivor区域。

1.老年代——标记-整理算法

老年代一般保存的是一些大对象,或者不被经常回收的对象,根据特点使用的标记-整理算法:如同名字一样,算法分为"标记"和“整理”两个阶段:首先先标记出所有需要回收的对象,在标记完成后统一回收所以被标记的对象进行整理,将被标记的对象都向一端移动,然后直接清理掉边界以外的内存。

四.HotSpot算法实现

上面说了我们怎么标记对象“死亡”和怎么进行垃圾回收的,但在HotSpot虚拟机在实现这些算法上是必须对算法的执行效率进行考量的。

1.安全点

在可达性分析中对执行的时间的敏感体现在GC停顿上,其意思是在整个分析的过程中看起来就像被冻结在某一个时间点上的,不可以出现分析的过程中引用关系在不断变化,如果这点得不到保证则分析的结果的准确性就得不到保障。这点是导致在GC进行时需要停顿所有的java执行线程。当执行系统停顿下来后,虚拟机并不需要全部上小文和全局所有的位置,虚拟机通过一个OopMap的数据结构在类加载的时候将对象的偏移量数据信息记录下来,所以GC扫描是就直接得到这些信息的。其实这些通过指令被加入进行记载对象信息的OopMap位置也叫做安全点,程序执行时并非所有点都可以停下来开始GC的,只有在到达安全点才能停顿。安全点机制程序执行中,在不太长的时间内会遇到可进入GC的安全点。在实际中会遇到在GC时有线程不再执行,例如线程被挂起了。这是我们需要安全区域去解决。

2.安全区域

安全区域是指在一段代码片段中,引用关心不会发生变化。在这个区域中的任意地方开始GC都是安全的。在代码执行到安全区域是,首先表示这直接进去安全区域,这样虚拟机在这段时间GC时就不用管那些标记为安全区域的线程了。当离开安全区域时首先得判断是GC分析是否完成,没完成则需要等待。

五.理解GC日志

gc原理以及gc日志剖析

这是上图打印的gc日志

[GC (System.gc()) [PSYoungGen: 6092K->448K(38400K)] 6092K->456K(125952K), 0.0051702 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]

PSYoungGen表示的是新生代gc不同垃圾收集器新生代名称不一样,6092K->448K(38400K)表示新生代大小的变化,6092K->456K(125952K)表示推内存的大小变化 后面表示用时。

[Full GC (System.gc()) [PSYoungGen: 448K->0K(38400K)] [ParOldGen: 8K->378K(87552K)] 456K->378K(125952K), [Metaspace: 3050K->3050K(1056768K)], 0.0056045 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

表示发生在老年代的gc(Major GC/Full GC) 他知识为伴随一次的新生代的gc(Minor GC),448K->0K(38400K)表示新生代内存变化,8K->378K(87552K) 老年代gc变化,456K->378K(125952K)表示gc前后堆内存的变化。

点赞
收藏
评论区
推荐文章
灯灯灯灯 灯灯灯灯
4年前
阿里面试被问到【垃圾回收器】,不会怎么办??
垃圾回收器GC分类与性能指标垃圾回收器概述1.垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的JVM来实现。2.由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本。3.从不同角度分析垃圾收集器,可以将GC分为不同的类型。Java不同版本新特性1.语法层面:Lambda表达式、switch、
Wesley13 Wesley13
3年前
java中的GC和内存泄漏
java中的GC1.GC是什么?为什么要有GC? GC是垃圾回收的意思。是指JVM清理不再使用的对象释放内存。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存.2\.需要GC的内存区域垃圾回收区域:主要针对无用堆对象回
Wesley13 Wesley13
3年前
java GC算法 垃圾收集器
GC算法垃圾收集器概述垃圾收集GarbageCollection通常被称为“GC”,它诞生于1960年MIT的Lisp语言,经过半个多世纪,目前已经十分成熟了。jvm中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方
灯灯灯灯 灯灯灯灯
4年前
【垃圾回收】全面解析,内含面试题及图文详解!!
垃圾回收概述和相关算法1.Java和C语言的区别,就在于垃圾收集技术和内存动态分配上,C语言没有垃圾收集技术,需要程序员手动的收集。2.垃圾收集,不是Java语言的伴生产物。早在1960年,第一门开始使用内存动态分配和垃圾收集技术的Lisp语言诞生。3.关于垃圾收集有三个经典问题:哪些内存需要回收?什么时候
Stella981 Stella981
3年前
JVM虚拟机调优实战(3)进阶调优篇
1.JVM内存分配与回收1.1MinorGc和FullGC有什么不同呢?   新生代GC(MinorGC):指发生新生代的的垃圾收集动作,MinorGC非常频繁,回收速度一般也比较快。   老年代GC(MajorGC/FullGC):指发生在老年代的GC,出现了MajorGC经常会伴随至少一次的MinorGC(并非绝对)
Wesley13 Wesley13
3年前
CIL锁,GIL与线程池的区别,进程池和线程池,同步与异步
一.GIL锁什么是GIL?全局解释器锁,是加在解释器上的互斥锁GC是python自带的内存管理机制,GC的工作原理:python中的内存管理使用的是应用计数,每个数会被加上一个整型的计数器,表示这个数据被引用的次数,当这个整数变为0时则表示该数据已经没有人使用,成为了垃圾数据,当内存占用达到某个阈值,GC会将其他线程挂起,然后执行垃圾清理操作,垃圾
Stella981 Stella981
3年前
JVM回收器与调优
定义:使用编程语言将GC算法实现出来,产生的程序就是垃圾搜集器了JVM给了三种选择:串行收集器、并行收集器、并发收集器串行搜集器(serialcollector):它只有一条GC线程,且就像前面说的,它在运行的时候需要暂停用户程序(stoptheworld)。并行搜集器(parallelcollector):它有多
Stella981 Stella981
3年前
JVM总结3
    垃圾收集GarbageCollection通常被称为“GC”,它诞生于1960年MIT的Lisp语言,经过半个多世纪,目前已经十分成熟了。    jvm 中,程序计数器、虚拟机栈、本地方法栈都是随线程而生随线程而灭,栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理,因此,我们的内存垃圾回收主要集中于java堆和
Stella981 Stella981
3年前
JVM汇总
GC的最根本原因:垃圾收集器的工作就是清除Java创建的对象,垃圾收集器需要清理的对象数量以及要执行的GC数量均取决于已创建的对象数量。因此,为了使你的系统在GC上表现良好,首先需要减少创建对象的数量。GC优化的两个目的:1.将进入老年代的对象数量降到最低2.减少FullGC的执行时间原则:将进
Stella981 Stella981
3年前
Python的垃圾回收机制
垃圾回收机制「垃圾回收(GC)」大家应该多多少少都了解过,什么是垃圾回收呢?垃圾回收GC的全拼是GarbageCollection,在维基百科的定义是:在计算机科学中,垃圾回收(英语:GarbageCollection,缩写为GC)是一种自动的内存管理机制。当一个电脑上的动态内存不再需要时,就应该予以释放,以让出内存,这种内存资源
京东云开发者 京东云开发者
11个月前
一次JVM GC长暂停的排查过程
背景在高并发下,Java程序的GC问题属于很典型的一类问题,带来的影响往往会被进一步放大。不管是「GC频率过快」还是「GC耗时太长」,由于GC期间都存在StopTheWorld问题,因此很容易导致服务超时,引发性能问题。事情最初是线上某应用垃圾收集出现Fu