【JVM】说说java中的堆区

news/2024/5/20 7:57:17 标签: jvm, , 新生代, 老年代, 永久代

(Heap)是被虚拟机所管理的最大的一块内存区域,在中,会有以下一些对象:

  • 朝生夕死的小对象,蜉蝣一般
  • 大对象,例如长数组,需要大量连续的内存空间
  • 长周期对象,存活很久,很能熬

因此,目前主流的JVM,利用可达性分析算法分析对象是否死亡,最后针对性地采用分代搜集算法回收死亡对象。判断对象是否死亡,可以先参考我的另外一篇文章【JAVA】如何判断对象已经死亡?

可以分为新生代老年代,用来存放不同类型的对象。如下图所示:


新生代

新生代含有3个区域,1个Eden区,2个Survivor区,可以分别称为from以及to区,from与to的大小相同。它们占用的大小比例默认为Eden:from:to=8:1:1,当然也可以通过参数-XX:SurvivorRatio来自定义比例。

新创建的对象都会处在Eden区,大对象会直接进入老年代,可以使用参数-XX:+PretenuerSizeThreshold来指定多大的对象。

新创建的对象优先在Eden区上分配,Eden区满了之后,会触发一次Minor GC,虚拟机会采用复制算法(不会产生内存碎片)先进行释放内存,回收死亡对象,然后将存活的对象一次性复制进from区域中。若from区域不够,则使用分派担保机制将部分对象直接推入老年代老年代空间不够,将触发一次Full GC。

发生过一次Minor GC之后,Eden区域基本空闲,新创建的对象依然在这块区域上分配,当Eden区域又满了之后,同样还是出发第二次Minor GC,这次GC将会回收Eden与from区域,将存活的对象一次性地复制进to区域中。

这些对象在新生代中每熬过一次Minor GC,对象的年龄就会加1,当年龄达到某一个阈值时(默认为15),将会被直接移到老年代中,可以使用参数-XX:MaxTenuringThreshold来指定这个阈值。

因为新生代区域上对象,创建频繁,死亡也频繁,因此Minor GC也会变得十分频繁,但是这种GC方式效率高,持续时间短

老年代

老年代中主要有老年对象(超过年龄阈值的对象)以及大对象。当老年代空间不足时,会触发一次Full GC,由于各个垃圾收集器的实现不同或处于效率考虑,可能会采用标记清除算法,也可能采用标记整理的算法回收死亡对象。

当然,也不是对象必须达到年龄阈值才会进入老年代中,如果Survivor内某个相同年龄下(比如10岁)的所有对象的大小总和超过Survivor区的一半,那么年龄≥10岁的对象将直接进入老年代

Full GC不像Minor GC那么频繁,但持续时间长。倘若频繁发生Full GC,会严重阻碍应用程序的执行。

也有一些博客会将Full GC与Major GC区分开来,认为他们的区别是Full GC会对整个进行回收,而Major GC只会对老年代进行回收。但其实现在已经不区分这两者了,很多性能监控工具也不再区分,现在大可认为Full GC与Major GC没有差别。


常用参数

(1)新生代初始大小:-XX:NewSize,最大:-Xmn(-XX:MaxNewSize)

(2)Eden区与1个Survivor区的比例:-XX:SurvivorRatio

如果新生代的大小为10M,新生代=1个Eden+2个Survivor,并且设置-XX:SurvivorRatio=8,那么此时Eden区占用8M,每个Survivor区各占1M。

(3)老年代初始大小:-XX:OldSize

(4)老年代新生代的比例:-XX:NewRatio

如果设置总大小为100M,=新生代+老年代,并且设置-XX:NewRatio=4,那么老年代大小是新生代的4倍,此时新生代占20M,老年代占80M。

(5)打印GC信息:-XX:+PrintGCDetails

(6)在GC前后打印信息:-XX:+PrintHeapAtGC

(7)设置进入老年代的年龄阈值:-XX:MaxTenuringThreshold

(8)设置直接进入老年代的大对象的大小阈值:-XX:+PretenuerSizeThreshold


Minor GC的触发条件

(1)Eden区空间不足,或者说Eden区放不下新创建的小对象。

Full GC触发条件

(1)老年代空间不足,此时执行Full GC后,老年代空间依旧不足的话,虚拟机会抛出 java.lang.OutOfMemoryError: Java heap space异常

(2)调用System.gc()方法,这只是通知或者是建议虚拟机进行Full GC,虚拟机可以根据情况选择是否执行。

(3)Minor GC时,将对象从Eden区与from区向to区转移,若to区空间不够,此时会将部分对象转移到老年代中,若此时老年代空间不够,将触发一次Full GC。

(4)永久代满(JDK1.7之前,方法区的实现-永久代还未被元空间取代)


关于分配担保机制与GC实验,可能要另开篇幅


http://www.niftyadmin.cn/n/1705250.html

相关文章

驾驭系统 做一个Windows XP的“***”(图)5

先睹Vista 先睹Vista只是一个开始,安全性和性能的提升才是下一代Windows的真正亮点。未来10年内,Vista将会是最安全、最快和最可靠的一个Windows版本。在经过4年的开发期后,它会于2006年晚些时候发布,Windows XP的这个后继者将会提…

GetSystemInfo

GetSystemInfo GetSystemInfo,Win32 API 函数。   函数说明:   GetSystemInfo返回关于当前系统的信息。   函数原型:   VOID GetSystemInfo   (   LPSYSTEM_INFO lpSystemInfo   );   参数表:   lpSystemInfo …

ListView控件演示01

此代码示例来自于微软的MSDN,在此基础进行了一些修改。 下面的代码示例创建一个 ListView 控件,其中带有三个指定的 ListViewItem 对象,而这三个对象中的每一项又带有三个指定的 ListViewItem.ListViewSubItem 对象。该示例还创建 ColumnHea…

sql 中的with as语句使用,用法

一、with 的用法 With alias_name as (select 1)[,alias_name as (select n) ]--中括号可以省略 Select …二、关键字概述 在标准的数据库中,如hive,Oracle,DB2,SQL SERVER,PostgreSQL都是支持WITH AS 语句进行递归查…

【JAVA】Spring事务的传播行为

前言 Spring为我们提供了巨大的便利,其中的事务增强特性,使得程序出错时,不需要我们进行手动回滚。Spring在Propagation定义了7种事务的传播行为: public enum Propagation {REQUIRED(TransactionDefinition.PROPAGATION_REQUIR…

Office文档在线编辑的实现-转

http://www.cnblogs.com/jianyi0115/Office xp之后的版本支持通过webdav协议(http的扩展)直接编辑服务器上的文件。IIS(6.0)支持webdav,这在IIS管理器的web服务扩展中可以看到.利用IIS作为webdav的服务器端,可以很容易的实现offic…

java代码保留两位小数的做法

java代码保留两位小数的做法 在日常Java开发中,少不了会有页面或界面上展示的数据保留小数点后两位的需求,这里列举了几种可行的方法(有更好的方法可以分享给我) import java.math.BigDecimal; import java.math.RoundingMode; …