JavaGC、新生代、老年代

Java 中的堆是 JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象。

在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young )又被划分为

三个区域:Eden、From Survivor、To Survivor。

这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。

堆的内存模型大致为:

从图中可以看出: 堆大小 =新生代 + 老年代。其中,堆的大小可以通过参数 –Xms、-Xmx 来指定。

(本人使用的是 JDK1.6,以下涉及的 JVM 默认值均以该版本为准。)
   默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 (该值可以通过参数 –XX:NewRatio 来指定

),即:新生代 ( Young ) = 1/3 的堆空间大小。老年代 ( Old ) = 2/3 的堆空间大小。其中,新生代 ( Young )

被细分为 Eden 和 两个 Survivor 区域,这两个 Survivor 区域分别被命名为 from 和 to,以示区分。

默认的,Edem : from : to = 8 :1 : 1 (可以通过参数–XX:SurvivorRatio 来设定 ),即: Eden = 8/10 的

新生代空间大小,from = to = 1/10 的新生代空间大小。

JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务,所以无论什么时候,总是有一块Survivor

区域是空闲着的。

因此,新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间。

GC 堆                                                                                  

Java 中的堆也是 GC收集垃圾的主要区域。GC 分为两种:Minor GC、FullGC ( 或称为 Major GC )。

Minor GC 是发生在新生代中的垃圾收集动作,所采用的是复制算法

新生代几乎是所有 Java 对象出生的地方,即 Java 对象申请的内存以及存放都是在这个地方。Java 中的大部

分对象通常不需长久存活,具有朝生夕灭的性质。

当一个对象被判定为 "死亡" 的时候,GC 就有责任来回收掉这部分对象的内存空间。新生代是 GC 收集垃圾的

频繁区域。

当对象在 Eden ( 包括一个 Survivor 区域,这里假设是 from 区域 ) 出生后,在经过一次 Minor GC后,如

果对象还存活,并且能够被另外一块 Survivor 区域所容纳(上面已经假设为 from 区域,这里应为 to 区域,

即 to 区域有足够的内存空间来存储 Eden 和 from 区域中存活的对象 ),则使用复制算法将这些仍然还存活的对

象复制到另外一块 Survivor 区域 ( 即 to 区域 ) 中,然后清理所使用过的 Eden以及 Survivor 区域 ( 即

from 区域 ),并且将这些对象的年龄设置为1,以后对象在 Survivor 区每熬过一次 Minor GC,就将对象的年

龄 + 1,当对象的年龄达到某个值时 ( 默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设定

 ),这些对象就会成为老年代。

但这也不是一定的,对于一些较大的对象 (即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代

Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法

现实的生活中,老年代的人通常会比新生代的人"早死"。堆内存中的老年代(Old)不同于这个,老年代里面的对象

几乎个个都是在 Survivor 区域中熬过来的,它们是不会那么容易就 "死掉" 了的。因此,Full GC发生的次数不

会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。


   另外,标记-清除算法收集垃圾的时候会产生许多的内存碎片 (即不连续的内存空间 ),此后需要为较大的对象

分配内存空间时,若无法找到足够的连续的内存空间,就会提前触发一次 GC 的收集动作。

GC 日志                                                                               

publicstaticvoid main(String[] args) {

Object obj= new Object();

System.gc();

System.out.println();

obj= new Object();

obj=new Object();

System.gc();

System.out.println();

}

设置 JVM 参数为 -XX:+PrintGCDetails,使得控制台能够显示 GC 相关的日志信息,执行上面代码,下面是其中

一次执行的结果。

Full GC 信息与 Minor GC的信息是相似的,这里就不一个一个的画出来了。

从 Full GC 信息可知,新生代可用的内存大小约为 18M,则新生代实际分配得到的内存空间约为 20M(为什么是

20M? 请继续看下面...)。老年代分得的内存大小约为 42M,堆的可用内存的大小约为 60M。可以计算出: 18432K

( 新生代可用空间 ) + 42112K ( 老年代空间 ) = 60544K ( 堆的可用空间 )

新生代约占堆大小的 1/3,老年代约占堆大小的 2/3。也可以看出,GC 对新生代的回收比较乐观,而对老年代

以及方法区的回收并不明显或者说不及新生代。

并且在这里 Full GC 耗时是 Minor GC 的 22.89 倍。

JVM 参数选项                                                                        

下面只列举其中的几个常用和容易掌握的配置选项

-Xms

初始堆大小。如:-Xms256m

-Xmx

最大堆大小。如:-Xmx512m

-Xmn

新生代大小。通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90%

-Xss

JDK1.5+ 每个线程堆栈大小为 1M,一般来说如果栈不是很深的话, 1M 是绝对够用了的。

-XX:NewRatio

新生代与老年代的比例,如 –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3

-XX:SurvivorRatio

新生代中 Eden 与 Survivor 的比值。默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10

-XX:PermSize

永久代(方法区)的初始大小

-XX:MaxPermSize

永久代(方法区)的最大值

-XX:+PrintGCDetails

打印 GC 信息

-XX:+HeapDumpOnOutOfMemoryError

让虚拟机在发生内存溢出时 Dump 出当前的内存堆转储快照,以便分析用

jvm GC的更多相关文章

  1. 如何避免后台IO高负载造成的长时间JVM GC停顿(转)

    译者著:其实本文的中心意思非常简单,没有耐心的读者建议直接拉到最后看结论部分,有兴趣的读者可以详细阅读一下. 原文发表于Linkedin Engineering,作者 Zhenyun Zhuang是L ...

  2. 【转载】Java性能优化之JVM GC(垃圾回收机制)

    文章来源:https://zhuanlan.zhihu.com/p/25539690 Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我 ...

  3. JVM GC机制

    垃圾收集主要是针对堆和方法区进行. 回收机制: 现在的JVM基本都使用分代回收机制,把堆中内存区域分为新生代,老年代. 新生代: Eden(80%) Survivor0(10%) Survivor1( ...

  4. 深入浅出 JVM GC(3)

    # 前言 在 深入浅出 JVM GC(2) 中,我们介绍了一些 GC 算法,GC 名词,同时也留下了一个问题,就是每个 GC 收集器的具体作用.有哪些 GC 收集器呢? Serial 串行收集器(只适 ...

  5. 深入浅出 JVM GC(2)

    # 前言 在 深入浅出 JVM GC(1) 中,限于上篇文章的篇幅,我们留下了一个问题 : 如何回收? 这篇文章将重点讲述这个问题. 在上篇文章中,我们也列出了一些大纲,今天我们就按照那个大纲来逐个讲 ...

  6. JVM 自带性能监测调优工具 (jstack、jstat)及 JVM GC 调优

    1. jstack:占用最多资源(CPU 内存)的Java代码 https://www.cnblogs.com/chengJAVA/p/5821218.html https://blog.csdn.n ...

  7. 理解JVM GC

    理解JVM GC对于我们把控Java应用有很大的帮助.下面我从运维角度,把网上的JVM相关的资料整理如下,以加深对JVM GC的理解.如有错误的地方,请看官指正. JVM内存使用分类 JVM的内存分区 ...

  8. Java性能优化之JVM GC(垃圾回收机制)

    Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.st ...

  9. JVM gc介绍

    Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放控件,既要写构造函数,又要写析构函数,很多时候都 ...

  10. 一夜搞懂 | JVM GC&内存分配

    前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习GC&内存分配? 时代发展到现在,如今的内存动态分配与内存回收技术已经相当成 ...

随机推荐

  1. Jquery之Bind方法参数传递与接收的三种方法

     方法一. function GetCode(event) { alert(event.data.foo); } $(document).ready(function() { $("#s ...

  2. 【Android 应用开发】Android开发 使用 adb logcat 显示 Android 日志

    作者 : 万境绝尘  转载请著名出处 eclipse 自带的 LogCat 工具太垃圾了, 开始用 adb logcat 在终端查看日志; 1. 解析 adb logcat 的帮助信息 在命令行中输入 ...

  3. sublime text (ST)一篇通(安装、配置、扩展、使用)

    sublime编辑器,功能插件多,可以扩展为IDE------------------------------------------- 1.安装 官网下载  http://www.sublimete ...

  4. python 2.4 的字符串转时间(日期减法取间隔时间)

    python 2.4中datetime有strftime方法,而无strptime方法.不能对字符串进行格式转换.比如不能将"2013-10-22"转化为日期. 2.4中字符串转日 ...

  5. Cocos2d中update与fixedUpdate的区别(二)

    关于update:方法的目的 update:方法的目的在于给你一个更新你的游戏(你游戏中的所有对象,标签等待)的机会,在它们被渲染到屏幕之前. 换句话说,如果你想要一些游戏对象显示在屏幕的特定位置,你 ...

  6. Android Support Design 控件 FloatingActionButton

    经常刚可以看到悬浮控件,比如印象笔记的下面那个绿色的悬浮按钮,这个控件非常简单也是来自Design Support Library中同理需要在android studio中加入依赖库:design库 ...

  7. 【算法导论】八皇后问题的算法实现(C、MATLAB、Python版)

    八皇后问题是一道经典的回溯问题.问题描述如下:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉?         看到这个问题,最容易想 ...

  8. rhel6.4 安装nodejs和Mysql DB服务

    rhel6.4 安装nodejs和Mysql DB服务 安装好redhat6.4虚拟机后, 安装软件: # yum install gcc-c++ openssl-devel Loaded plugi ...

  9. ffdshow 源代码分析 5: 位图覆盖滤镜(总结)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  10. 漫谈jdbc

    本文可作为北京尚学堂jdbc课程的学习笔记; 简介 jdbc是什么东西? jdbc全称(Java Database Connectivity java数据库连接) 它是干什么的? 至于它是干什么的,那 ...