JVM架构(007)_java堆内存是什么样的

转载 2016年08月29日 15:04:44

1.堆内存是什么样的

了解jvm实例模型看这里:jvm实例的结构是什么样的 
了解java内存框架看这里:jvm是如何管理内存的 
了解堆栈的区别看这里:java堆和栈有什么区别 
每一个jvm实例都会被分配一个被所有线程共享堆内存空间,用来存放对象和数组,作为jvm的数据集中管理区,存取效率空间释放就成为了重中之重,jvm通过多区架构来完成这两个目标的达成。其结构如下:

这里写图片描述

2、什么是新生代

新生代(Young Generation)主要是用来存放新生的对象。

新生代又被进一步划分为Eden区(伊甸园区)和Survivor区(幸存区,包含空间相等的S0、S1区,或者说From、To区,没有先后顺序,是Copying算法的需要)。

大多数情况下,java中新建的对象都是在新生代上分配的,通过Copying算法来进行分配内存垃圾回收

了解堆的Copying算法看这里:什么是新生代的Copying算法

有两种情况下java新创建的对象会直接到旧生代

  1. 占用空间大的对象/数组,且对象中无外部引用的对象。

  2. 通过启动参数上面进行设置-XX:PretenureSizeThreshold=1024(单位是字节),如果对象超过此大小,就直接分配到旧生代。此外,并行垃圾回收器可以在运行期决定那些对象可以直接创建在旧生代。

了解垃圾回收机制看这里:java垃圾回收机制是什么 
通过-Xmn设置新生代的大小,通过-XX:SurvivorRatio设置Eden区和Survivor区的比值,有些垃圾回收器会对S0或者S1进行动态的调整。

新生对象根据Copying算法Eden区/S0区或者Eden区/S1区中分配,Eden区的对象量达到阈值后,发生一次新生代GC

3、什么是老生代

老生代(Old Generation)主要存放应用程序中生命周期长的内存对象。

在新生代中经过多次垃圾回收仍然存活的对象,会被存放到老生代中。老生代通过标记/整理算法来清理无用内存。

多次回收之后仍然存活的对象,大小是-Xms减去-Xmn

老生代通过-XX:MaxTenuringThreshold设置最大年龄阈值,每个对象有“对象年龄计数器”,对象由新生代Eden区(伊甸园区)收集到Survivor区(幸存区)后,年龄+1。新生代垃圾清理(GC)后,年龄+1。依次,当年龄>=阈值后进入老生代。

对于年龄阈值有两中特殊情况:

  1. 如果在Survivor区(幸存区)中所有相同年龄对象占用了空间的一半以上,大于等于上述年龄的对象直接进入老生代。

  2. 占用空间大于-XX:PretenureSizeThreshold设定阈值的大对象(比如大的数组),会直接进入老生代。

4、什么是永久代

永久代(Permanent Generation)方法区,主要存放Class和Meta等永久保存的信息(如类、方法、字符串等)。

Class在被加载的时候被放入PermGen space区域。它和存放对象实例的堆内存不同,垃圾收集(GC)不会在主程序运行期对PermGen space进行清理,所以如果你的程序会加载了很多Class的话,就很可能出现PermGen space错误

这里要说明的是,以上的堆内存机构是Java 8之前的结构,在新版本的Java中有如下变化:

  • Java 7版本时把驻留字符串(intentd string)放到了老生代区。

  • Java 8中,永久代在堆中被移除,取而代之的是本地元空间,这与Oracle JRockit和IBM JVM类似,JVM也开始使用本地化的内存,来存放类的元数据。Java 8的堆内存结构如下:

这里写图片描述

相关文章推荐

Java千百问_07JVM架构(007)_java堆内存是什么样的

点击进入_更多_Java千百问1.堆内存是什么样的了解jvm实例模型看这里:jvm实例的结构是什么样的 了解java内存框架看这里:jvm是如何管理内存的 了解堆栈的区别看这里:java堆和栈有什...

巩固java(二)----JVM堆内存结构及垃圾回收机制

前言:        我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制。 目录:         1....

java 堆内存与JVM参数

堆内存 Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。 在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生...
  • zljjava
  • zljjava
  • 2014年03月04日 15:15
  • 931

《java performance》翻译 第七章jvm调优:堆内存设置

设置jvm堆内存     到目前为止,还没有为调优jvm的内存占用采取任何调优动作。下面这个步骤讲述了如何来确定一个应用应该使用的jvm内存大小。这个步骤的目标是帮助调优人员找出应用的常驻内存大...
  • e5945
  • e5945
  • 2013年03月06日 22:55
  • 1554

深入理解Java之JVM堆内存分配

Java堆是被所有线程共享的一块内存区域,所有对象和数组都在堆上进行内存分配。为了进行高效的垃圾回收,虚拟机把堆内存划分成新生代、老年代和永久代(1.8中无永久代,使用metaspace实现)三块区域...

优化Java堆内存大小的五个技巧

  • 2016年06月28日 13:46
  • 23KB
  • 下载

优化Java堆内存大小的五个技巧

  • 2012年11月03日 07:28
  • 24KB
  • 下载

JDK8中JVM堆内存划分

说明JDK8新的堆内存划分方法,解析Matedata space作为新的内存空间跟JDK7的永久性内存相比有何不同。...
  • jia20003
  • jia20003
  • 2016年02月20日 11:05
  • 10343

Java中堆内存与栈内存分配浅析

  • 2011年11月02日 15:53
  • 7KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JVM架构(007)_java堆内存是什么样的
举报原因:
原因补充:

(最多只允许输入30个字)