JVM之堆

JVM之堆

 

堆只要放实例对象和数组,当堆内存需要占用的空间大于我们设置的只,就会出OutOfMemoryError。

 

 

堆内存结构

 

  • JVM堆(Heap)= 新生代 + 旧生代
  • 新生代(Young)= Eden区 + From Survivor区 + To Survivor区


 

 

堆内存的默认比例:

 

  • 新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )
  • 新生代 ( Young ) = 1/3 的堆空间大小。老年代 ( Old ) = 2/3 的堆空间大小
  • Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定 )
  • Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小

注意:

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

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

 

 

 

新生代

 

所有新生成的对象首先都是放在年轻代。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。

 

大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当一个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当另一个Survivor区也满了的时候,从前一个Survivor区复制过来的并且此时还存活的对象,将可能被复制到年老代。

 

如何延长对象在新生代的存活时间

 

  • 加大新生代,这样就不会那么容易发生垃圾回收
  • 增加Survivor区的个数,其实Survivor区可以不止两个
  • 修改阈值-XX:MaxTenuringThreshold,默认是15,对象经过15次Minor GC后会复制到旧生代

针对新生代的垃圾回收是Minor GC

 

减少Minor GC的方法:加大新生代

 

 

 

旧生代

 

在年轻代中经历了N次(可配置)垃圾回收后仍然存活的对象,就会被复制到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。

 

针对年老代的垃圾回收即 Full GC

 

减少Full GC的方法:减少Minor GC次数或者加大旧生代

 

 

 

这样分配堆内存主要跟垃圾回收的机制有关,后面再详细讲解垃圾回收,简单步骤如下:

 

  • 新实例化的对象,会存放在Eden
  • 当Eden空间不够的时候,就复制到Survivor区
  • 如果Survivor区的空间不够,就会触发Minor GC(新生代的垃圾回收),将无用的对象回收掉,释放内存,剩下的对象复制到To Survivor区
  • 下一次垃圾回收,就会将Eden和To Survivor区回收后剩下的对象,复制到From Survivor区
  • 在复制的过程中,对象的复制一次年龄会加1,到达一定次数(默认15),对象就要被移动到旧生代
  • 当旧生代空间不足时,才会进行Full GC(全垃圾回收)

 

 

JVM堆的相关配置



 

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。

JVM最大分配的内存由-Xmx指定,默认是物理内存的 1/4但小于1G。

 

 

 

Out of Memory 的两个原因

 

1. 年老代溢出,表现为:java.lang.OutOfMemoryError:Javaheapspace

这是最常见的情况,产生的原因可能是:设置的内存参数Xmx过小或程序的内存泄露及使用不当问题。

例如循环上万次的字符串处理、创建上千万个对象、在一段代码内申请上百M甚至上G的内存。还有的时候虽然不会报内存溢出,却会使系统不间断的垃圾回收,也无法处理其它请求。这种情况下除了检查程序、打印堆内存等方法排查,还可以借助一些内存分析工具,比如MAT就很不错。

 

2. 永久代溢出,表现为:java.lang.OutOfMemoryError:PermGenspace

 

通常由于永久代设置过小,动态加载了大量Java类而导致溢出,解决办法唯有将参数 -XX:MaxPermSize 调大(一般256m能满足绝大多数应用程序需求)。将部分Java类放到容器共享区(例如Tomcat share lib)去加载的办法也是一个思路,但前提是容器里部署了多个应用,且这些应用有大量的共享类库。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值