码迷,mamicode.com
首页 > 其他好文 > 详细

JVM垃圾回收机制(一)

时间:2016-01-02 20:32:52      阅读:322      评论:0      收藏:0      [点我收藏+]

标签:

  垃圾回收器

  垃圾回收器主要负责:

    1. 分配内存;

    2. 保证所有正在被引用的对象还存在在内存中; 

    3. 回收不再被程序所引用的对象所占内存;

  Hotspot VM提供的垃圾回收器是一个分代的垃圾回收器(Generational GC),它将内存划分为不同的阶段,即不同生命周期的对象被放置在不同的内存空间中。这样的设计是基于弱年代假设(Weak Generational Hypothesis):大多数对象会很快变得不可达,只有很少有老对象指向新对象的引用。这种方式可以减少垃圾回收的停顿时间以及大范围对象的回收成本。Hotspot VM将其堆空间划分为3个分代空间:

    1. 年轻代Young Generation

      a. Java应用在分配Java对象时,这些对象会被分配到年轻代堆空间中去;

      b. 这个空间大多是小对象并且会被频繁回收;

      c. 由于年轻代堆空间的垃圾回收会很频繁,因此其垃圾回收算法会更加重视回收效率;

    2. 年老代Old Generationn

      a. 年轻代堆空间的长期存活对象会转移到(也许是永久性转移)年老代堆空间;

      b. 这个堆空间通常比年轻代的堆空间大,并且其空间增长速度较缓;

      c. 由于大部分JVM堆空间都分配给了年老代,因此其垃圾回收算法需要更节省空间,此算法需要能够处理低垃圾密度的堆空间;

    3. 持久代Permanent Generation

      a. 存放VM和Java类的元数据(metadata),以及interned字符串和类的静态变量;

  其堆空间示意图如下:

技术分享

  其年轻代又分为三个空间:

    1. Eden——绝大多数刚刚被创建的对象会存放在此;

    2. Survivor1——在Eden空间执行了第一次GC之后,存活的对象被移动到此;

    3. Survivor2;

  注意:当一个Survivor空间饱和,还在存活的对象会被移动到另一个Survivor空间。之后会清空已经饱和的那个Survivor空间,Survivor空间必须至少有一个为空。如果两个Survivor空间都有数据,或者两个空间都是空的,那一定标志着你的系统出现了某种错误。

  GC类型

  JDK7一共提供了5种GC类型:

    1. Serial GC;

    2. Parallel GC;

    3. Parallel Old GC (Parallel Compacting GC);

    4. Concurrent Mark & Sweep GC  (or “CMS”);

    5. Garbage First (G1) GC;

  其中,Serial GC不应该被用在服务器上。这种GC类型在单核CPU的桌面电脑时代就存在了。使用Serial GC会显著的降低应用的性能指标。

  

  垃圾回收方式

  当这三个分代的堆空间比较紧张或没有足够的空间来为新到的请求分配的时候,垃圾回收机制就会起作用。有两种的垃圾回收方式:次收集(Minor GC)和全收集(Full GC)。当年轻代堆空间满了的时候,会触发Minor GC将还存活的对象移到年老代堆空间。当年老代堆空间满了的时候,会触发一个覆盖全范围的对象堆的Full GC。

  次收集

    1. 当年轻代堆空间紧张时会被触发;

    2. 相对于全收集而言,收集间隔较短;

  全收集

    1. 当老年代或者持久代堆空间满了,会触发全收集操作;

    2. 可以使用System.gc()方法来显式的启动全收集;

    3. 全收集一般根据堆大小的不同,需要的时间不尽相同,但一般会比较长;

  全收集通常时间很长,并且是程序无法延迟执行或者无法达到吞吐量目标的主因。GC的目标是去减少程序运行过程中垃圾回收的频率。为了达到这个目的,可以从这两方面入手:

    1. 从系统方面考虑:

      a. 尽量采用大堆,但是不要大到需要系统从磁盘上“换”页。一般而言,可用的RAM(没有被系统进程占用的)的80%都应该分配给JVM。

      b. Java堆空间越大,垃圾回收器和java应用在吞吐量(throughput)和延迟执行(latency)方面的效果越好。

    2. 从应用方面考虑:

      a. 减少对象分配(object allocations)操作,或者采用对象保留(object retention)方式有助于减小存活的数据大小,这也可以反过来帮助垃圾回收做的更好。

 

  如果老年代的对象需要引用一个新生代的对象,会发生什么呢?

  为了解决这个问题,年老代中存在一个”card table“,他是一个512 byte大小的块。所有年老代的对象指向年轻代对象的引用都会被记录在这个表中。当对年轻代执行GC的时候,只需要查询card table来决定是否可以被收集,而不用查询整个老年代。这个card table由一个write barrier来管理。write barrier给GC带来了很大的性能提升,虽然由此可能带来一些开销,但GC的整体时间被显著的减少。

     技术分享

  

JVM垃圾回收机制(一)

标签:

原文地址:http://www.cnblogs.com/tianex/p/5095113.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!