JVM调优之:内存分配参数

1. 设置最大堆内存(-Xmx)

java应用程序可以使用的最大堆内存可以使用-Xmx 参数指定,最大堆内存是新生代和年老年代之和的最大值。

下面代码演示在java虚拟机被设定了最大堆内存之后,创建不能被回收的java对象,会发生“java.lang.OutOfMemoryError: Java heap space”异常。

设定参数:-Xmx5M

public static void main(String[] args) {
    Vector v = new Vector();
    for (int i=1;i<=10;i++){
        byte[] b = new byte[1024*1024];//给次循环占用1M空间
        v.add(b);//强引用,不会被GC回收
        System.out.println(i+"M is allocated");
    }
    System.out.println("Max memory :"+Runtime.getRuntime().maxMemory()/1024/1024+"M");//系统可用最大内存
}

运行结果

1M is allocated
2M is allocated
3M is allocated
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

因为堆内存最大值为5M,在被占用了3M之后,剩余的空闲内存已经不够1M了,所以会发生内存溢出错误。

设定参数:-Xmx15M  运行结果说明最大堆内存为15M时,满足创建10个1M大小的数组。

1M is allocated
2M is allocated
3M is allocated
4M is allocated
5M is allocated
6M is allocated
7M is allocated
8M is allocated
9M is allocated
10M is allocated
Max memory :15M

2. 设置最小堆内存(-Xms)

使用JVM参数-Xms可以设置系统最小堆空间。java应用程序在运行时,首先会被分配-Xms指定的内存大小,并尽可能尝试在这个空间段内运行,当-Xms指定的内存实在无法满足程序运行时,JVM才会向操作系统申请更多的内存,直到内存大小达到-Xmx指定的值。若超过-Xmx的值则抛出OutOfMemoryError。

当参数-Xms设置过小时,JVM为了保证系统尽可能在该空间范围内运行,就会更加频繁地进行GC操作,这样就会对系统产生一定的影响。

代码演示-Xms堆内存设置对GC频次的影响

public static void main(String[] args){
    Vector v = new Vector();
    for (int i=1;i<=10;i++){
        byte[] b = new byte[1024*1024];//给次循环占用1M空间
        v.add(b);//强引用,不会被GC回收
        if(v.size() == 3){
            System.out.println("累计3M时清空内存");
            v.clear();//清除引用,GC可以对没有引用的对象回收
        }
    }
}

参数:-Xmx11m -Xms4m -verbose:gc,系统进行4次GC,1次Full GC,以下运行结果

[GC (Allocation Failure)  505K->504K(3584K), 0.0011018 secs]
[GC (Allocation Failure)  1016K->648K(3584K), 0.0125823 secs]
累计3M时清空内存
累计3M时清空内存
[GC (Allocation Failure)  7925K->7872K(9216K), 0.0039725 secs]
[GC (Allocation Failure)  7872K->7872K(9728K), 0.0010522 secs]
[Full GC (Allocation Failure)  7872K->1649K(4608K), 0.0225880 secs]
累计3M时清空内存

参数:-Xmx11m -Xms11m -verbose:gc,系统进行5次GC,0次Full GC,以下运行结果

[GC (Allocation Failure)  2272K->1672K(11776K), 0.0013209 secs]
累计3M时清空内存
[GC (Allocation Failure)  3809K->1704K(11776K), 0.0009657 secs]
[GC (Allocation Failure)  3820K->3784K(11776K), 0.0012901 secs]
累计3M时清空内存
[GC (Allocation Failure)  5897K->4808K(11776K), 0.0010995 secs]
累计3M时清空内存
[GC (Allocation Failure)  6919K->4808K(11776K), 0.0007631 secs]

注意:JVM会试图将系统尽可能限制在-Xms中,因此当实际占用内存接近-Xms时就会触发Full GC。

3.设置新生代(-Xmn)

参数-Xmn用于设置新生代空间大小,当新生代设置较大时老年代空间就会相应的减小,所以这个参数的设置对系统新能和GC行为有很大影响,新生代的大小一般为整个堆内存的1/4到1/3左右。

在Hot Spot虚拟机中,-XX:NewSize用于设置新生代初始大小,-XX:MaxNewSize用于设置新生代最大值。通常情况下-Xmn已经可以满足我们绝大多说需要,设置-Xmn效果就等于设置了相同的-XX:NewSize和-XX:MaxNewSize,若设置不同的-XX:MaxNewSize和-XX:NewSize反而会导致内存震荡。

4.设置持久代(JDK6)

在JDK6版本中:

--XX:PermSize:设置持久带初始大小

XX:MaxPermSize:设置持久带最大值

5.元空间设置(JDK8)

JDK8版本中:

默认情况下元空间大小受本地内存大小影响,也可以通过参数指定元空间大小。

-XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。

-XX:MaxMetaspaceSize,最大空间,默认是没有限制的。

6.设置线程栈(-Xss)

线程栈是线程执行时开辟的一块独立内存空间。

例如配置:-Xss1M,表示设置每个线程拥有1M的栈空间,在本机计算机上可以开1803个线程,当修改-Xss20M时在本机计算机上只能开81个线程了。

如果指定了最大堆内存,则会发现系统所能支持的线程数与堆内存还有关系,服务器本地内存一定的情况下,堆内存占用越大,相应的线程栈所能占用的内存就会变小。

7.堆的比例分配

生产上面更多的是希望对堆空间进行比例分配。

-XX:SurvivorRatio是用来设置新生代中eden区和s0空间的比例关系。s0和s1空间大小是相同的,并在MinorGC后,会互换角色。

-XX:SurvivorRatio = eden/s0=eden/s1

如-Xmn10M -XX:SurvivorRatio=8,则表示eden =8M,s0=1M,s1=1M.

如-Xmn10M -XX:SurvivorRatio=2,则表示eden=5M,s0=2.5M,s1=2.5M

-XX:NewRatio用来设置新生代和老年代比例

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

如-Xms20M -Xmx20M -XXNewRatio=2,则表示 新生代=6.6M 老年代=13.3M。

8.堆分配参数总结

-Xms:设置初始堆大小。

-Xmx:设置最大堆大小。

-Xss:设置线程栈大小。

-XX:NewSize:设置新生代大小。

-XX:SurvivorRatio:设置eden/s0比例。

-XX:TargetSurvivorRatio:设置survivor区可使用率,当survivor区的空间使用率达到这个值时会将对象送入老年代。

-XX:NewRatio:设置老年代/新生代比例。

-XX:MetaspaceSize:设置初始元空间大小。

-XX:MaxMetaspaceSize:设置最大元空间大小。

 

转载于:https://my.oschina.net/u/3100849/blog/887997

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值