`

JAVA基础知识回顾-----Java堆内存设计原理-----随想随写

 
阅读更多

Java堆内存设计原理

   通常来说,堆中存储通过new字符创建的对象或者数组;

  JVM中堆内存分为2大块,Permanent space和 Heap space

  •   Permanent即持久代(Permanent Generation),主要存储了Java类的定义信息,与垃圾收集器要收集的Java对象关系不大
  •   Heap={Old+new={Eden,from,to}},Old代表年老代,New代表年轻代,年老代和年轻代的划分对垃圾回收器的影响比较大

       

Permanent Generation 持久代

   用来存放静态数据类型

 

年轻代、年老代

    所有新生的对象首先放在年轻代,年轻代的目标就是尽可能的在此将生命周期短的对象通过垃圾回收器进行回收。年轻代分为3个去,Eden,Survivor(From,To其中,From和To区地位是平等的);

    大部分对象是在Eden去生成档Eden区满时,还存活的对象被复制到Survivor区中的From区或者To区,当其中一个Survivor区满时,还存活的对象就被复制到另一个Survivor区,当另一个Survivor区也满的时候,这时候从另一个Survivor区复制过来的仍然存活的对象就有可能被复制到Old区;

 

针对年轻代的回收    Young GC
针对年老代的回收     Full     GC

 

内存申请过程:

1.JVM会试图为相关的Java对象在Eden区申请内存空间;

2.如果在Eden区内存中空间足够,则申请结束;否则,进行下一步;

3.JVM试图释放Eden区所有不活跃的对象(Young GC),释放后空间仍然不足的话,则JVM会试图将活跃的对象存放至Survivor区中

4.Survivor区是Eden区与年老代的中间件。当年老代空间足够时,在Survivor区中存活了一定次数的对象会被移到年老代;

5.当年老代空间不足时,JVM会在年老代执行完全的垃圾回收(Full GC);

6.当Full GC 后,若Survivor区和年老代仍然无法存放从Eden区复制过来的对象,这时会出现JVM无法在Eden区为新的对象申请内存空间,即“Out of Memory”

 

出现错误情况

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

  原因:设置的内存参数Xmx过小或内存泄漏及使用不当问题

 

2.持久代溢出,表现为java.lang OutofMemoryError:PermGenSpace

  原因:持久代设置过小,动态加载大量Java对象导致溢出

  解决方法:将 -xx MaxPermSize调大

 

参数说明(来自网络):

-Xms :初始堆大小。只要启动,就占用的堆大小
-Xmx :最大堆大小。java.lang.OutOfMemoryError: Java heap这个错误可以通过配置-Xms和-Xmx参数来设置
-Xss:栈大小分配。栈是每个线程私有的区域,通常只有几百K大小,决定了函数调用的深度,而局部变量、参数都分配到栈上。当出现大量局部变量,递归时,会发生栈空间OOM(java.lang.StackOverflowError)之类的错误。
-XX:NewSize=n :设置新生代大小的绝对值
-XX:NewRatio=n: 设置年轻代和年老代的比值。比如设置为3,则新生代:老年代=1:3,新生代占1/4的总heap大小。
-XX:SurvivorRatio=n :年轻代中Eden区与两个Survivor区的比值。注意Survivor区有from和to两个。比如设置为8时,那么eden:from:to=8:1:1
-XX:MaxPermSize=n :设置持久代大小 ;java.lang.OutOfMemoryError: PermGen space这个OOM错误需要合理调大PermSize和MaxPermSize大小。
-XX:HeapDumpOnOutOfMemoryError :发生OOM时转储堆到文件,这是一个非常好的诊断方法。
-XX:HeapDumpPath :导出堆的转储文件路径
-XX:OnOutOfMemoryError:OOM时,执行一个脚本,比如发送邮件报警,重启程序。后面跟着一个脚本的路径。

  • 大小: 29 KB
7
2
分享到:
评论
1 楼 masuweng 2016-08-11  

相关推荐

Global site tag (gtag.js) - Google Analytics