JAVAgc 介绍

来源:互联网 发布:网络盒子怎样双清 编辑:程序博客网 时间:2024/05/24 07:39

java GC介绍

jvm 常用参数介绍

-Xms                         初始堆大小

-Xmx                         最大堆大小

-Xmn                         年轻代大小

-XX:PermSize                 设置持久代(perm gen)初始值

-XX:MaxPermSize             设置持久代最大值

-Xss                          每个线程的堆栈大小

-XX:SurvivorRatio             Eden区与Survivor区的大小比值

(并行回收gc可以使用-XX:InitialSurvivorRadio调整  并行回收这个比例不是不变的会根据程序运行动态调整)

-XX:pretenureSizeThreshold    对象超过多大是直接在旧生代分配

-XX:MaxTenuringThreshold  垃圾最大年龄

-XX:MaxGCPauseMillis: 设置大于0的毫秒数,收集器尽可能在该时间内完成垃圾回收(Parallel Scavenge专用)

-XX:CMSInitiatingOccupancyFraction =70使用cms作为垃圾回收
使用70%后开始CMS收集

-XX:GCTimeRatio:大于0小于100的整数,即垃圾回收时间占总时间的比率,设置越小则希望垃圾回收所占时间越小,CPU能花更多的时间进行系统操作,提高吞吐量(Parallel Scavenge专用)

XX+UseCMSCompactAtFullCollection  CMS是不会移动内存的,因此,这个非常容易产生碎片,导致内存不够用,因此,内存的压缩这个时候就会被启用。增加这个参数是个好习惯。这个参数是多少次fullgC进行压缩默认为零

 

jvm 垃圾收集器介绍

 

图展示了7种作用于不同分代的收集器,如果两个收集器之间有连线,说明他们可以搭配使用。

1.serial 收集器(复制算法)

    该收集器历史最悠久,在jdk1.3.1之前是新生代收集的唯一选择。这是一个单线程的收集器。

缺点:由于单线程收集慢,导致stop word时间长。影响用户体验

优点:由于单线程,可以专心干事,不需要线程间的交互,在cpu核数不多的情况下是个不错的选择(目前 client模式下默认的新生代收集器)

2.ParNew 收集器(复制算法

    该收集器是Serial的多线程版本,就是采用多线程进行垃圾回收。

优点:如果是多核的服务器,多线程收集,比单线程快,stop word的时间短。

缺点:如果在cpu核数不多的情况下,性能不如serial收集器,

说明:由于jdk1.5推出了cms收集器,但由于他不能和Parallel scavenge一起工作,

只能和Serial 收集器配合使用。这样导致年轻代的收集很慢拖累整个程序,cms在这个时期使用就得不偿失了。ParNew收集器的出现让cms可以走向舞台。

3.Parallel Scavenge(复制算法,server模式下默认的收集器(附录介绍))

   Parallel Scavenge 注重的是吞吐量的多线程收集器

    吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集停顿时间),例:虚拟器总共

运行了100分钟,其中垃圾回收花掉1分钟,吞吐量为(99/(99+1))*100%=99%

Parallel Scavenge  可以调整两个参数

-XX:MaxGCPauseMillis收集器尽可能在该时间内完成垃圾回收,单位毫秒。

-XX:GCTimeRatio   ,即垃圾回收时间占总时间的比率(0-100).

4.Serial Old(标记-整理算法

Serial Old 是Seriall 的老年代版本,是一个单线程收集器。使用标记-整理算法(给client 模式下的虚拟机使用)。有两个用处

1.jdk1.5以及以前版本中和parallelscavenge 收集器搭配使用。

2作为CMS 收集器的后备方案,当发生ConcurrentMode Failure 时使用

5. Parallel Old 收集器(标记-整理算法

Parallel Old 是Parallel Scavenge的老年代版本,在jdk1.6才开始提供使用的,在此之前新生代的Parallel Scavenge 一直处于比较尴尬的地位,原因是如果新生代选择了Parallel Scavenge

老年代就必须选择Serial Old,这样使用Parallel Scavenge未必能达到整体的吞吐量优先。

6.CMS(标记-清除)(以最少用户停顿时间为目标)

吞吐量优先和最少用户停顿时间优先的区别

吞吐量算法已经说过了,最少用户停顿时间是指stop word时间最短。

   该收集器比其他收集器复杂一些主要有如下4步。

   1.初始标记

   2.并发标记

   3.重新标记

   4.并发清除

该收集器的优点:

并发,并发收集,用户停顿时间少。

缺点:1.对cpu敏感,在并发阶段他不会引起用户停顿,但会占用用户的一些cpu资源

默认回收线程数为(cpu数量+3/4)。

2.cms收集器无法处理浮动垃圾

  浮动垃圾是指在并发处理阶段,用户线程还在运行,自然会产生垃圾,这一部分在标记之后,这次无法清理,只能等下一次清理。这部分垃圾称为浮动垃圾。

由于是和用户线程的cms垃圾回收并行运行,cms收集器不能等年老代满了才去收集,必须预留一部分空间给用户线程放对象。如果在并发收集阶段预留空间不够的话,就会发生Concurent Mode Failure  采用备用方案。(-XX:CMSInitiatingOccupancyFraction调整预留空间大小

3.最后一个是

由于标记清除,会有碎片产生。

7.G 1(jdk1.7 7u4 正式提供,oracle主打的收集器)

 主要是以下4步

1.初始标记

2.并发标记

3.最终标记

4.筛选回收

优点

1.并发与并行

G1 可以充分利用cpu的资源,来缩短stopword 时间

2.分代收集,他不需要其他收集器配合使用,就能单独管理堆.他对新创建的对象和长期存活的对象处理方式不一样

3.空间整合整体是标记-整理,两个Region上是复制算法

4.可预测停顿,除了降低停顿还关注吞吐量。

 

 

怎样读懂GC日志

下面MInGc

package com.linkage.testgc;

//minorGC -Xms40M -Xmx40M -Xmn16M-verbose:gc -XX:+PrintGCDetails

public classMinGC {

    public static void main(String[] args)throws Exception {

        MemoryObjectobject = newMemoryObject(1024*1024);

        MemoryObjectobject2 = newMemoryObject(1024*1024*2);

        for(int i=0;i<2;i++){

            happenMinorGC(9);

            Thread.sleep(2000);

        }

       

       

    }

 private staticvoidhappenMinorGC(inthappenMinorGCindex) throws Exception

  {

        for(inti=0;i<happenMinorGCindex;i++){

            if(i==happenMinorGCindex-1){

                System.out.println("minor gc should happen");

                Thread.sleep(2000);

            }

            newMemoryObject(1024*1024);

        }

       

  }

static classMemoryObject{

     private byte[]bytes;

     public MemoryObject(int ObjetSize){

         this.bytes=newbyte[ObjetSize];

     }

     

 }

}

 

[GC [PSYoungGen:16343K->1592K(18432K)] 16343K->3640K(38912K), 0.0026914 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

minor gc should happen

minor gc should happen

[GC [PSYoungGen:17617K->1624K(18432K)] 19665K->3672K(38912K), 0.0087863 secs] [Times:user=0.00 sys=0.00, real=0.01 secs]

Heap

 

下面FULL gc

 

package com.linkage.testgc;

 

import java.util.ArrayList;

import java.util.List;

//-Xms20M -Xmx20M -Xmn10M-verbose:gc -XX:+PrintGCDetails

public classFullGc {

    public static void main(String[] args)throws Exception {

       List<MemoryObject> objects= newArrayList<MemoryObject>();

       for(int i=0;i<5;i++){

       objects.add(new MemoryObject(1024*1024));

       }

       //让对象直接进入年老代

        System.gc();

        Thread.sleep(2000);

        System.out.println("调用gc完毕");

        objects.clear();

        for(int i=0;i<10;i++){

            objects.add(newMemoryObject(1024*1024));

            if(i%3==0){

                objects.remove(0);

            }

        }

        Thread.sleep(5000);

    }

   

   

}

[GC [PSYoungGen:5956K->600K(9216K)] 5956K->5720K(19456K), 0.0032144 secs] [Times:user=0.00 sys=0.00, real=0.00 secs]

[Full GC [PSYoungGen:600K->0K(9216K)] [ParOldGen: 5120K->5591K(10240K)]5720K->5591K(19456K) [PSPermGen: 2543K->2542K(21504K)], 0.0120996 secs][Times: user=0.05 sys=0.00, real=0.01 secs]

调用gc完毕

[Full GC [PSYoungGen:7507K->0K(9216K)] [ParOldGen: 5591K->4567K(10240K)]13098K->4567K(19456K) [PSPermGen: 2545K->2545K(21504K)], 0.0161243 secs][Times: user=0.03 sys=0.00, real=0.02 secs]

其中 Full GC 代表GC的类型  PSYoungGen代表gc的区域,7507K->0K(9216K)] 7507代表回收钱内存量0代表回收后内存量 9216K代表总内存量,其他的类似。

Times: user=0.03 sys=0.00, real=0.02 secs 代表gc的耗时

 

附录

.client 和server模式介绍

一.client 又称为C1 ,较为轻量级,只做少量性能开销比高的优化,占用内存较少

主要优化手段有

1.方法内联

2.去虚拟化

3.冗余消除

二.server compiler          又称为C2 较为重量级,采用了大量传统优化技术优化,占用较大内存

逃逸分析是c2优化的基础(运行状况判断变量是否会被外部读取,如果不被外部读取就是逃逸的)分为方法逃逸,线程逃逸

1.标量替换

2栈上分配

3.同步消除等

原创粉丝点击