java垃圾回收详解

java中一个进程运行时的内存使用情况如下图:

主要讲解堆区的垃圾回收

其中堆是JVM占用比例最大的一块区域,用来存放对象实例。现在JVM大多将堆分为老年代,新生代和永久区。老年代与新生代比例为2:1。新生代分为一个Eden和两个Survivor区域,比例为8:1:1。

堆区详解如下:

 

在年轻代,分为三部分,其中eden(伊甸园)是用来存放新生成出来的对象,当进行一次GC时,没有被清除的对象会存放在幸存区,其中from和to,每次必定会有一个是空的,当to区存放数据时,下一次GC就相当于上一次的from。

新生成的对象没有被GC的会从eden复制到from,下一次GC依然没有被GC的会将eden和from的复制到to,依次重复,当存储的对象达到设置的年龄阈值后,会将这些对象复制到Old区,(每经历一次GC年龄值就会+1)老年区回收速度较慢,GC频率较低。当Old区达到设置的阈值时一般会触发FGC

//当Eden区没有足够的空间进行分配时,虚拟机将发起一次Minor GC

Minor GC 和 Full GC的区别

       新生代GC(Minor GC):Minor GC指发生在新生代的GC,因为新生代的Java对象大多都是朝生夕死,所以Minor GC非常频繁,一般回收速度也比较快。当Eden空间不足以为对象分配内存时,会触发Minor GC。

       老年代GC(Full GC/Major GC):Full GC指发生在老年代的GC,出现了Full GC一般会伴随着至少一次的Minor GC(老年代的对象大部分是Minor GC过程中从新生代进入老年代),比如:分配担保失败。Full GC的速度一般会比Minor GC慢10倍以上。当老年代内存不足或者显式调用System.gc()方法时,会触发Full GC。

注意:

1.YGC频繁一般不会对程序性能造成严重影响

2.FGC频繁会对程序造成严重影响,FGC有一个说法stw(stop the world)是指,进行fgc时会停止所有进程,专心进行gc,无法处理请求,会对程序性能造成严重影响。

3.GC不会处理永久区的数据

 

jvm参数设置

Heap(堆)内存大小设置
  Xmx2g: 最大堆内存 2g
  Xms2g:最小堆内存 2g
New Generation(新生代)内存大小设置
  Xmn256m:设置JVM的新生代内存大小(Xmn 是将NewSize与MaxNewSize设为一致。256m),同下面两个参数
    -XX:NewSize=256m
    -XX:MaxNewSize=256m
Stack(栈)内存大小设置
  Xss1m:每个线程都会产生一个栈。在相同物理内存下,减小这个值能生成更多的线程。如果这个值太小会影响方法调用的深度。
Permanent Generation(永久代)内存大小设置
  XX: PermSize=128m 设置持久代初始内存大小128M
  XX:MaxPermSize=512m 设置持久代最大内存大小512M

其他
  -XX:InitialSurvivorRatio 新生代Eden/Survivor空间的初始比例;

  -XX:Newratio 新生代和老年代的内存比例;

  -XX:MaxMetaspaceSize 元数据区最大内存
1.Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3。
2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成。
注意:
1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。
2.Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。

 

posted @ 2019-09-09 11:18  默晓梦  阅读(305)  评论(0编辑  收藏  举报