垃圾收集是java与c/c++的最大不同。有了jvm的自动垃圾收集机制,就可以让程序员专注于程序逻辑开发,

而不是花费大量的时间是考虑一个变量应该在什么时候去释放。

下面我们就来简单说一下java的垃圾收集相关的一些东西

首先一下问题是,jvm是如何判断一个对象已经变成了”垃圾“的呢?

两个方法:

1)引用记数法:

  为每个对象保存一个引用的数量,每增加一个引用这个值就加1,每减少一个引用就减1.如果这个记数变为

0了,就说明这个对象已经不再被使用了。那么jvm就认为这个对象是可以回收的了。

  但是这个方法有一个缺点,就是无法解决循环引用的问题。A引用B,B也引用A,如果A,B两个对象都不再

被使用了,那么这两个对象其实都是可以被回收的,但是他们的引用记数不为0.所以用这个办法就没有办法回收了。

2)要搜索算法:

  从一系列的”GC Roots“对象开始向下搜索,搜索走过的路径称为引用链。当一个对象到”GC Roots“之间没有

引用链时,被称为引用不过达。引用不可到的对象被认为是可回收的对象。

  java中可以当做为”GC Roots“对象的包括

    1:jvm虚拟机栈(栈帧中的局部变量表)中引用的对象

    2:方法区中的类静态属性引用的对象

    3:常量池中的常量引用的对象

    4:本地方法栈JNI(native方法)中的引用的对象

  根搜索算法判断对象是否存活,与对象的引用有关。java中有4种引用,强、软、弱、虚,这4种引用的强度依

次降低。

  强引用就好像是生活必须品,在java语言中存在最普遍的一种引用,就比较"Object obj = new Object()"这种,

只要强引用存在,垃圾收集器就不会对对象进行回收

  软引用是还有些用处,但不是必须的.在内存充足的时候垃圾收集顺并不会对这些对象进行收集,但是当内存不足的时候,

这些对象就要被划分到回收的范围内了,但是也不是马上回回收,软引用对象至少要经过2个GC周期才能回收干净.

  弱引用是一种比软引用还要弱的引用,这种对象只要发生了GC就回被回收.

  虚引用是最弱的一种引用,他的存在并不会影响对象的寿命.不能通过虚引用得到对象的实例.加入虚引用只是为了在对象被回收时能够收到系统的知道.

根搜索算法中不可达的对象也不是”非死不可的“,这时候只是处于”缓刑“期。一个对象要被”处死“,最少要经过两

个标记阶段。

  当对象第一次引用不可达时,对象会被标记和筛选。如果这个对象没有重写Object的finalize方法或是finalize

方法已经被调用过了,那么这个对象在下次gc的时候就会被回收了。

  如果这个对象重写了finalize方法,那么jvm会把这个对象放入一个F-Queue队列中。这个队列中的所有对象都会

等待finalize方法被执行,finalize方法是对象最后一次也是唯一一次逃脱被回收命运的机会。随后jvm会创建一条低优先

级的线程去执行F-Queue中的对象的finalize方法,但是JVM并不保证会等待这个方法会执行完,所以这个方法也不能保证

一定会被执行。执行完这个方法后这个对象又回被标记一次,在下次搜索标记的时候如果这个对象还是”不可达的“,那么

这个对象就回被真正的回收。

下面再说一下jvm有哪些垃圾回收算法,通常大家说的就是4种:

  1)标记--清除 算法

    这个算法就是把”垃圾“对象标记出来,然后就直接回收掉了。所以这个算法就有一个很明显的缺点,会产生很

多的内存碎片。

  2)复制 算法

    这个算法就是把内存分为两块空间,每次只使用其中的一块。垃圾收集的时候把不需要回收的对象复制到另一块没有

使用的内存中去。这样就在回收的同时对内存进行了整理。但是这也有一个缺点,就是需要额外的内存空间,内存空间利用率

只有一半。这在内存紧张的境况下是不行的。

  3)标记--整理 算法

    这个算法就是把”垃圾“对象标记出来,然后把所有不需要回收的对象从内存的一端移到的另一端,这个算法是对标记

清除的改进,回收的同时还对碎片进行了整理。

  4)分代收集

  这个其实不应该叫垃圾回收算法,应该算是一种垃圾收集策略。 这种做法是把内存划分成不同的区域,通常叫做”青年代“和

”老年代“。而”青年代“又分为Eden区和survivor区,survivor区又分为from和to两个区

  jvm对不同的区域采用不同的回收算法。 ”青年代“区域比较小,存放的对象都是寿命很短的对象,因此采用的是复制算法,

而"老年代"都是生存期比较久的对象,适合采用标记--清除和标记--整理算法

 最后说下垃圾收集器

  1) Serial收集器

    serial收集器是client级虚拟机(windows上的32位jvm或者运行在单cpu上的jvm)的默认收集器.

它的特点是单线程,在minor GC和full GC的时候都要把应用暂停.在full GC的时候他会对老年代的对象进行

压缩整理.

  2)throughput收集器

    throughput收集器是server级虚拟机(多cpu的unix或64位jvm)上的默认收集器.它的特殊是在垃圾收集

的时候是多线程进行的,能够最大限度的发挥应用的吞吐量.并且throughput收集器在垃圾收集的时候会进行碎片整理,

同样的缺点是也是在full GC的时候回暂停应用的所有线程.

  3) CMS收集器

    CMS收集器也是多线程进行垃圾收集的,并且他消除了throughput在full GC的时候会暂停应用的缺点,

CMS会定时的对老年代的对象进行扫描,并及时的进行回收.CMS只在minor GC和后台扫描时发生极其短暂的停顿.

这个代价是需要花费额外的CPU使用.CMS的缺点是在对老年代对象回收的时候没有进行碎片整理.如果碎片太多,没有

办法存放对象,或者CPU无法满足时,CMS收集器将退化到serial收集器,对碎片进行压缩整理和垃圾收集,之后就又回恢复

到多线程方式

  4) G1收集器

G1收集器的设计初衷是为了尽量缩短处理超大堆(大于4G)时产生的停顿的,G1属于concurrent收集器,也是多线程进行垃圾

收集,但是它比CMS收集器发生full GC的概率更小,并且G1收集器在垃圾收集时会进行碎片整理.

垃圾收集器的选择要根据具体的物理机的特点,加上一些会理的参数设置,才能使应用更好的发挥效率.

转载请注明出处:http://www.cnblogs.com/taixuyingcai/

jvm垃圾收集小记的更多相关文章

  1. JVM垃圾收集算法(标记-清除、复制、标记-整理)

     [JVM垃圾收集算法] 1)标记-清除算法: 标记阶段:先通过根节点,标记所有从根节点开始的对象,未被标记的为垃圾对象(错了吧?) 清除阶段:清除所有未被标记的对象 2)复制算法: 将原有的内存空间 ...

  2. JVM垃圾收集算法

    JVM垃圾收集 1. 判断对象是否存活 引用计数算法 对象添加一个引用计数器,每个地方引用它,计数器值加+1:当引用失效,计算器值减1:任何时刻计数器为0的对象不可能被使用.引用计数算法实现简单,高效 ...

  3. JVM调优:HotSpot JVM垃圾收集器

    HotSpot JVM垃圾收集器 - Snooper - 博客园https://www.cnblogs.com/snooper/p/8718478.html

  4. JVM垃圾收集器-Parallel Scavenge收集器

    今天我给大家讲讲JVM垃圾收集器-Parallel Scavenge收集器 Parallel Scavenge收集器 Parallel Scavenge收集器也是一个新生代收集器,它也是使用复制算法的 ...

  5. JVM垃圾收集(Java Garbage Collection / Java GC)

    JVM垃圾收集(Java Garbage Collection / Java GC) Java7 Java8 JDK1.8之后将最初的永久代取消了,由元空间取代. 堆内存调优简介 public sta ...

  6. 7种JVM垃圾收集器特点,优劣势、及使用场景

    今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集器就是内存回收的具体实现. 一.常见的垃圾收集器有3类 1.新生代的收集器包括 Serial PraNew Pa ...

  7. 【006】【JVM——垃圾收集器总结】

     Java虚拟机学习总结文件夹 JVM--垃圾收集器总结 垃圾收集器概览 收集算法是内存回收的方法论.垃圾收集据是内存回收的详细实现.Java虚拟机规范中对垃圾收集器应该怎样实现没有规定.不同的厂 ...

  8. 第五章 JVM垃圾收集器(1)

    说明:垃圾回收算法是理论,垃圾收集器是回收算法的实现,关于回收算法,见<第四章 JVM垃圾回收算法> 1.七种垃圾收集器 Serial(串行GC)-- 复制 ParNew(并行GC)-- ...

  9. 第六章 JVM垃圾收集器(2)

    上一章记录了几种常见的垃圾收集器,见<第五章 JVM垃圾收集器(1)> 1.G1 说明: 从上图来看,G1与CMS相比,仅在最后的"筛选回收"部分不同(CMS是并发清除 ...

随机推荐

  1. [iOS Animation]-CALayer 变换

    变换 很不幸,没人能告诉你母体是什么,你只能自己体会 -- 骇客帝国 在第四章“可视效果”中,我们研究了一些增强图层和它的内容显示效果的一些技术,在这一章中,我们将要研究可以用来对图层旋转,摆放或者扭 ...

  2. JS中的事件大全

    一般事件  onClick            鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDblClick        鼠标双击事件 onMouseDown        鼠标上的按 ...

  3. STM32/GD32芯片信息(转)

    源:STM32/GD32芯片信息 因为需要自动适配芯片进行系统配置,所以我们有必要通过读取一些系统寄存器来获取必要信息.我们的代码需要兼容STM32F1/GD32F1/STM32F0/STM32F4 ...

  4. iOS强制切换横屏、竖屏

    切换横竖屏最直接的方式是调用device的setOrientation方法.但是从sdk3.0以后,这个方法转为似有API,如果要上AppStore的话,要慎用! if ([[UIDevice cur ...

  5. IOS开发中长按的手势事件编程

    长按手势事件: 长按按钮1S后改变按钮颜色: // 长按事件 #import "ViewController.h" @interface ViewController (){ UI ...

  6. 转载自前端开发:CSS设置滚动条样式

    浏览器默认的滚动条样子太过屌丝了,得自己动手整整.记得IE浏览器有几个设置滚条的样式,不过比较鸡肋,只能设置颜色之类的,而且webkit下面也不支持.无意间看到网易邮箱的滚动条样子很好看,一开始以为是 ...

  7. Linq左关联 右关联 内关联

    1.左连接: var LeftJoin = from emp in ListOfEmployees join dept in ListOfDepartment on emp.DeptID equals ...

  8. struts配置文件和国际化

    一.加载包struts2-core-2.3.24.1.jar struts-default.xml :各种栈 org.apache.struts2 -->> default.propert ...

  9. object-c中的BOOL类型

    object-c中的布尔类型比C语言中的bool类型早了10年,它具有YES和NO两种值.在object-c中的布尔类型BOOL实际上是一种带符号的字符类型(signed char),它使用的空间是1 ...

  10. C# 存储过程使用方法

                CREATE PROCEDURE [dbo].[GetNameById] @studentid varchar(8), @studentname nvarchar(50) OU ...