全面认识JVM垃圾回收机制

开发 后端
JVM使用的是分代垃圾回收的方式,主要是因为在程序运行的时候会有两大特点,第一:大多数对象在创建后很快就没有对象使用它了,第二就是大多数在一直被使用的对象很少再去引用新创建的对象。

这里向大家简单介绍一下JVM垃圾回收的相关知识,JVM使用的是分代垃圾回收的方式,可以将Java对象分为"年轻"对象和"年老"对象,JVM将内存堆(Heap)分为两个区域,一个是"年轻"区,另一个是"老"区,Java将这两个区域分别称作是"新生代"和"老生代"。

JVM垃圾回收的相关知识

JVM使用的是分代垃圾回收的方式,主要是因为在程序运行的时候会有如下特点:

◆大多数对象在创建后很快就没有对象使用它了。

◆大多数在一直被使用的对象很少再去引用新创建的对象。

因此就将Java对象分为"年轻"对象和"年老"对象,JVM将内存堆(Heap)分为两个区域,一个是"年轻"区,另一个是"老"区,Java将这两个区域分别称作是"新生代"和"老生代"。

"新生代"区域中,绝大多数新创建的对象都存放在这个区域里,此区域一般来说较小而且JVM垃圾回收频率较高,同时因为"新生代"采用的算法和其存放的对象的特点,使该区域JVM垃圾回收的效率也非常高。

而"老生代"区域中存放的是在"新生代"中生存了较长时间的对象,这些对象将被转移到"老生代"区。这个区域一般要大一些而且增长的速度相对于"新生代"要慢一些,"老生代"JVM垃圾回收的执行频率也会低很多。

由于JVM在JVM垃圾回收处理时会消耗一定的系统资源,因此有时候通过JVM启动的时候添加相关参数来控制"新生代"区域的大小,来调整JVM垃圾回收处理的频率非常有用。以便于我们更合理的利用系统资源。

"新生代"区域设置参数是"-Xmn",用这个参数可以制定"新生代"区域的大小。

我们来举一个例子说明:

我们就用系统自带的程序作为例子,在命令行上键入如下指令:

  1. CDC:\java\demo\jfc\SwingSet2[回车]C:\java\demo\jfc\SwingSet2> 
  2. java-jar-verbose:gc-Xmn4mXX:+PrintGCDetailsSwingSet2.jar[回车]  
  3.  
  4.  

 上面加入了一个新的参数"XX:+PrintGCDetails",这个参数能够打印出GC的详细信息。屏幕输出如下(节选): 

  1. [GC[DefNew:3469K->84K(3712K),0.0007778secs]23035K-> 
  2. 19679K(28728K),0.0009191secs][GC[DefNew:3284K-> 
  3. 171K(3712K),0.0007283secs]22878K-> 
  4. 19766K(28728K),0.0008669secs][GC[DefNew:3476K->
  5. 260K(3712K),0.0008504secs]23071K-> 
  6. 19855K(28728K),0.0009862secs][GC[DefNew:3502K-> 
  7. 87K(3712K),0.0009267secs]23096K-> 
  8. 19682K(28728K),0.0010610secs]  

我们需要解释一下输出的详细内容的意思,拿第一行输出来说:

"DefNew:3469K->84K(3712K),0.0007778secs"是指"新生代"的JVM垃圾回收情况,这里的意思是从占用3469K内存空间变为84K内存空间,用时0.0007778秒。

"23035K->19679K(28728K),0.0009191secs"是指总体GC的回收情况,整体堆空间占用从23035K降低到19679K的水平,用时0.0009191秒。

那么,这时候我们在将"新生代"的内存设为8M,并把堆的最大可控值设定为32M,再去执行,键入如下指令:

  1. java-jar-verbose:gc-Xmn8m-Xmx32mXX:+PrintGCDetailsSwingSet2.jar[回车]  
  2.  

得到的结果如下(节选): 

  1. [GC[DefNew:6633K->6633K(7424K),0.0000684secs]
  2. [Tenured:18740K->18820K(24576K),0.0636505secs]25374K-> 
  3. 18820K(32000K),0.0639274secs][GC[DefNew:6646K-> 
  4. 6646K(7424K),0.0002581secs][Tenured:18820K-> 
  5. 18884K(24576K),0.0651957secs]25467K-> 
  6. 18884K(32000K),0.0658804secs][GC[DefNew:6611K-> 
  7. 6611K(7424K),0.0000668secs][Tenured:18884K-> 
  8. 18505K(24576K),0.0931406secs]25496K-> 
  9. 18505K(32000K),0.0934295secs]  

这个结果说明:

"[DefNew:6633K->6633K(7424K),0.0000684secs]"是指"新生代"的JVM垃圾回收情况,这里的意思是从占用6633K内存空间变为6633K内存空间,用时0.0000684秒。
"25374K->18820K(32000K),0.0639274secs"是指总体GC的回收情况,整体堆空间占用从25374K降低到18820K的水平,用时0.0639274秒。
"[Tenured:18740K->18820K(24576K),0.0636505secs]"是指"老生代"GC的回收情况,整体堆空间占用从18740K降低到18820K的水平,用时0.0009012秒。

通过这些参数的调整我们可以看到在处理垃圾收集问题时,从JVM垃圾回收的频率是时间方面的变化,我们可以根据不同程序的不同情况予以调整。

最后有必要提一下GC的相关参数:

-XX:+PrintGCDetails显示GC的详细信息
-XX:+PrintGCApplicationConcurrentTime打印应用执行的时间
-XX:+PrintGCApplicationStoppedTime打印应用被暂停的时间
注:":"后的"+"号表示开启此选项,如果是"-"号那么表示关闭此选项。
 

【编辑推荐】

  1. JVM垃圾回收机制使用秘笈
  2. JVM垃圾回收面临的问题
  3. 调用weblogic设置jvmheap大小
  4. 详解Tomcat配置JVM参数步骤
  5. 深入学习JVM内存设置原理和调优

 

 

责任编辑:佚名 来源: 51cto.com
相关推荐

2010-09-25 15:33:19

JVM垃圾回收

2010-09-16 15:10:24

JVM垃圾回收机制

2021-05-27 21:47:12

Python垃圾回收

2021-11-05 15:23:20

JVM回收算法

2010-09-26 16:42:04

JVM内存组成JVM垃圾回收

2010-10-13 10:24:38

垃圾回收机制JVMJava

2010-09-26 11:22:22

JVM垃圾回收JVM

2017-08-17 15:40:08

大数据Python垃圾回收机制

2017-03-03 09:26:48

PHP垃圾回收机制

2009-06-23 14:15:00

Java垃圾回收

2011-07-04 16:48:56

JAVA垃圾回收机制GC

2017-06-12 17:38:32

Python垃圾回收引用

2011-06-28 12:39:34

Java垃圾回收

2015-06-04 09:38:39

Java垃圾回收机

2021-12-07 08:01:33

Javascript 垃圾回收机制前端

2009-12-09 17:28:34

PHP垃圾回收机制

2011-12-26 09:50:05

.NET垃圾回收

2024-02-22 17:15:22

JS垃圾回收机制

2017-10-12 12:41:11

PHP圾回收机制变量容器

2019-08-19 12:50:00

Go垃圾回收前端
点赞
收藏

51CTO技术栈公众号