浅谈java垃圾回收(一)

本文简述java垃圾回收机制自己的一点理解,希望能对java学习的朋友有一点帮助,谢谢;

先了解下JVM:

JVM百度百科详情https://baike.so.com/doc/1063579-1125177.html

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

1.什么是java的垃圾回收

java GC百度百科地址(https://baike.so.com/doc/9559973-9904818.html

 垃圾回收—GC(Garbage Collection),JAVA特有功能,垃圾收集意味着程序不再需要的对象是"无用信息",这些信息将被丢弃,在大多时候这些被丢弃的信息,java会自动回收;它与“java面向编程”一样是java语言的特性之一;它与“ c/c++语言”最大区别是不用手动调用 free()  和 delete() 释放内存。GC 主要是处理 Java堆Heap ,也就是作用在 Java虚拟机 用于存放对象实例的内存区域,(Java堆又称为GC堆)。JVM能够完成内存分配和内存回收,虽然降低了开发难度,避免了像C/C++直接操作内存的危险。但也正因为太过于依赖JVM去完成内存管理,导致很多Java开发者不再关心内存分配,导致很多程序低效、耗内存问题。因此开发者需要主动了解GC机制,充分利用有限的内存的程序,才能写出更高效的程序。

2.垃圾回收的特点

总结为一下几点:

1.自动回收机制,JVM会判断一段程序是不是有用,在无用的情况下该段程序会有一定的内存消耗,而JVM的垃圾回收机制会在判断完成之后自动释放该代码占用的内存,以确保程序的高效运行;

2.垃圾收集能自动释放内存空间,减轻编程的负担,提高编程效率;

3.自动回收内存碎片(碎片是分配给对象的内存块之间的空闲内存洞);

4.垃圾收集的开销影响程序性能(JVM会追踪运行程序中有用的对象,可能程序会运行很长时间,他会一直追踪直到程序终止无用,再进行内存回收;还有就是垃圾回收的算法存在一定的问题);

 

3.GC算法

职能:

(1)发现无用信息对象;(检测垃圾

(2)回收被无用对象占用的内存空间,使该空间可被程序再次使用。(回收垃圾

GC算法有好多,下边列举几个常用的作对比:

方法名称 特点
引用计数法 1.占用资源:因为每个对象都需要维护一个计数器,每次指针有更新都伴随着计数器的更新,一定程度上占用了计算资源 
2.占用内存:计数器需要占用一定的内存,为了安全起见,计数器值的上限要大于所有对象的上限,这也是一笔不小的开销 
3.实现复杂,无法解决循环计数
标记清除算法 1.算法简单,实现简单 
2.碎片化:由于只是将垃圾对象清除掉,对于存活对象不做处理,所以由于存活对象分布的不连续性,会导致可用内存被分割成一块块的。
3.与写时复制技术不兼容:写时复制(Copy On Write)是一个很重要的思想,可以优化内存占用或者提升并发环境下的性能。
复制算法

1.效率快:相比于标记清除算法,复制算法在标记阶段,只需要标记哪些对象是活动的就可以了,相比于标记清除算法需要遍历所有的对象,性能上有提升

2.不会发生碎片化:同样相比于标记清除算法,由于存活下来的对象会在To区中连续的分配,因此不会像标记清除算法那样,需要维护碎片空间

3.分配速度快:由于不会发生碎片化,如果有一个新的对象请求内存,那么分配时可以直接追加在From区已用内存之后,分配的速度快

4.内存使用率低:由于复制算法把内存分成了两块,那么对于对象的可用空间来说,仅仅是其他算法的一半

5.自对象的递归复制:一个对象通常会关联一些自对象。在复制这些对象的时候,还需要递归的去处理它的自对象,这通常会产生一定的开销。同时,在递归调用时,存在着函数栈的消耗,潜藏着栈溢出的风险

分代收集算法 分堆回收,新老交换,回收效率高
自适应算法 监控堆,选择适当的垃圾回收器

4.常用垃圾回收器

垃圾回收器有很多,本文不做一一赘述,下边主要介绍Serial收集器、  ParallelScavenge收集器、CMS收集器;

1.Serial收集器(串行回收器)

JDK1.3之前广泛使用这个收集器,目前也是ClientVM下 ServerVM 4核4GB以下机器的默认垃圾回收器。串行收集器并不是只能使用一个CPU进行收集,而是当JVM需要进行垃圾回收的时候,需要中断所有的用户线程,知道它回收结束为止,因此又号称“Stop The World” 的垃圾回收器。注意,JVM中文名称为java虚拟机,因此它就像一台虚拟的电脑一样在工作,而其中的每一个线程就被认为是JVM的一个处理器,因此大家看到图中的CPU0、CPU1实际为用户的线程,而不是真正机器的CPU。

2.  ParallelScavenge收集器(吞吐量优先的收集器)

所提到的吞吐量=程序运行时间/(JVM执行回收的时间+程序运行时间),假设程序运行了100分钟,JVM的垃圾回收占用1分钟,那么吞吐量就是99%。在当今网络告诉发达的今天,良好的响应速度是提升用户体验的一个重要指标,多核并行云计算的发展要求程序尽可能的使用CPU和内存资源,尽快的计算出最终结果,因此在交互不多的云端,比较适合使用该回收器。

3.CMS收集器

CMS又称响应时间优先(最短回收停顿)的回收器,使用并发模式回收垃圾,使用标记-清除算法,CMS对CPU是非常敏感的,它的回收线程数=(CPU+3)/4,因此CPU核心数越多,GC回收时占用CPU资源率越低;

CMS模式主要分为四个过程

初始标记(CMS initial mark)

并发标记(CMS concurrent mark)

重新标记(CMS remark)

并发清除(CMS concurrent sweep)

在初始标记的时候,需要中断所有用户线程,在并发标记阶段,用户线程和标记线程

并发执行,而在这个过程中,随着内存引用关系的变化,可能会发生原来标记的对象被释放,进而引发新的垃圾,因此可能会产生一系列的浮动垃圾,不能被回收,浮动垃圾过多也可能导致回收失败。

5.JVM怎么判断对象可以回收了

1,对象没有引用

2,作用域发生未捕获异常

3,程序在作用域正常执行完毕

4,程序执行了System.exit()

5,程序发生意外终止(被杀进程等)

java 垃圾回收本次就先这么多,下次继续谈!!!

本人才疏学浅,文中如出现不对的地方请在评论区指出,谢谢!!!

原创不易,转载时请注明出处,谢谢!!!

猜你喜欢

转载自blog.csdn.net/Java_monkeys/article/details/85680671