JVM调优系列(二)——JVM内存分配解析

来源:互联网 发布:软件开发流程 ppt 编辑:程序博客网 时间:2024/06/01 10:09

一、设置堆内存

1、-Xmx

     指定最大堆内存=新生代+老年代;在最大堆内存范围内,将会一直为对象分配空间,直到超过这个值内存溢出。

public static void main(String[] args) {Vector v=new Vector();System.out.println("Max memory="+Runtime.getRuntime().maxMemory()/1024/1024 +"M");for(int  i=1;i<=10;i++){byte[] b=new byte[1024*1024]; //每个循环分配1M内存v.add(b);System.out.println(i+"M is allocated");}
     当设置最大堆内存为7m时(-Xmx7m),执行结果如下

Max memory=7M1M is allocated2M is allocated3M is allocated4M is allocated5M is allocated6M is allocatedException in thread "main" java.lang.OutOfMemoryError: Java heap spaceat com.taotao.redis.MemoryTest.main(MemoryTest.java:22)
在为第7个对象分配堆内存时,程序抛出outOfMemoryError。若将最大堆内存设置大些,则能为更多的byte数组分配空间。

2、-Xms

     设置系统的最小堆空间,也就是JVM启动时,所占操作系统的内存大小。

     注意:JVM会试图将系统内存可控制在最小堆内存范围内,当实际内存要触及最小堆大小时,会触发一次Full GC(清理整个堆空间的垃圾回收方式),垃圾回收过程还是耗时的,所以将最小堆内存设置大些时,可以在系统运行初期减少GC的次数和耗时。

 3、-Xmn

     设置新生代大小,因为新生代和老年代总和为Xmx的值,所以当最大堆已经设定时,一个较大的新生代会减少老年代的大小,这对系统垃圾回收有很大的影响。一般设置为整个堆空间的1/4到1/3;

4、-XX:NewSize

     新生代初始值(最小值)

5、-XX:MaxNewSize 

     设置新生代最大值

     一般设置Xmn已经可以满足绝大部分应用需求,等同于设置了相同的-XX:NewSize和-XX:MaxNewSize 

 6、堆的比例分配

     -XX:SurvivorRatio:设置新生代中,eden和s0空间的比例关系。

     -XX:NewRatio:老年代/新生代

二、方法区(又名持久代)

     方法区主要为常量、类定义分配空间,所以方法区的大小直接决定了系统支持多少个类定义和常量。

1、-XX:MaxPermSize

     设置方法区最大值 一般为64m即可,若依然出现永久区溢出,可以设置成128m。

2、-XX:PermSize

     设置持久代的初始值(最小值) 

三、虚拟机栈内存分配 

     虚拟机栈主要为程序的局部变量、调用提供内存空间,太小导致程序运行时空间不足或达不到程序调用深度,导致程序异常退出。太大舍得开设线程所需内存成本升高,系统支持的总线程数下降。

1、-Xss

     设置线程栈的大小, -Xss1m 表示每个线程拥有1MB栈空间。

四、总结

     对于JVM的内存分配,不仅需要知道博主总结的内存模型各部分所对应的分配策略,还需要针对上文中,每一个区域所对应的管理对象,结合程序特点,合理的分配好内存空间,并使得相互之间有机的协调工作。另外有兴趣也可以做相应的测试验证,面对内存溢出等问题有迹可循。


0 0
原创粉丝点击