JVM调优的相关设置

Java Heap分为3个区,YoungOldPermanentYoung保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象。

JVM的Heap分配可以使用-X参数设定,

-Xms

初始Heap大小

-Xmx

java heap最大值

-Xmn

young generationheap大小

 

JVM有2个GC线程。第一个线程负责回收Heap的Young区。第二个线程在Heap不足时,遍历整个Heap,将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn。不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。

为什么一些程序频繁发生GC?有如下原因:

1、程序内调用了System.gc()或Runtime.gc()。

2、一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC。

3、Java的Heap太小,一般默认的Heap值都很小。

4频繁实例化对象,Release对象。此时尽量保存并重用对象,例如使用StringBuffer()和String()。

 

如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态。

许多Server端的Java程序每次GC后最好能有65%的剩余空间。

经验之谈:

1) Server JVM 最好将 -Xms  -Xmx 设为相同值。为了优化 GC ,最好让 -Xmn 值约等于 -Xmx  1/3 

2) 一个GUI程序最好是每10到20 秒间运行一次GC ,每次在半秒之内完成 

3) 增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。 

 

JVM运行模式分server和client两种,他们对字节码优化的策略不同: 

Client主要优化对用户交互的响应速度,Client Mode 的装载速度和消耗内存方面都是比较有优势 

Server主要优化后台运行的代码,使用server模式可以提高性能,启动比client模式慢,长期运行则比client模式快。当该参数不指定时,虚拟机自动检测主机是否为服务器,如果是则以server模式启动,否则以client模式启动,J2SE5.0检测的根据是至少2个CPU和最低2GB内存。

 

 

Stack的设定   

    -Xss

    每个线程的 Stack 大小

每个线程都有他自己的Stack。Stack的大小限制着线程的数量。如果Stack过大容易导致内存溢漏。-Xss参数决定Stack大小,例如-Xss1024K,要求是1024的整数倍。如果Stack太小,则会导致Stack溢漏。

2009-7-12

年头变啦,内存变得如大白菜,每个新装的机器都2G以上的内存,甚至4G,也不是什么新闻。而软件‘吃’内存的情况则变化不大(除了VIsta)。但是JVM初始占用还停留在几年前的情况下,确实没有跟上软件和硬件的发展。而像Tomcat, JBoss, Eclipse,也考虑到每台机器的内存情况,所以初始话定义都很低,经常会抛内存溢出Bug。

JVM规范中,定义了以下三种内存溢出:

  java.lang.StackOverflowError:(很少)

  java.lang.OutOfMemoryErrorheap space(比较常见)

  java.lang.OutOfMemoryError: PermGen space (经常出现)

  java.lang.OutOfMemoryError: PermGen space 这个异常比较常见,是说JVM里的Perm内存区的异常溢出,Permanent区则负责保存反射对象,由于JVM在默认的情况下,Perm默认为64M,而很多程序需要大量的Perm区内存,尤其使用到像Spring等框架的时候,由于需要使用到动态生成类,而这些类不能被GC自动释放,所以导致OutOfMemoryError: PermGen space异常。解决方法很简单,增大JVM -XX:MaxPermSize 启动参数,就可以解决这个问题,如过使用的是默认变量通常是64M[5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.],改成128M就可以了,-XX:MaxPermSize=128m。如果已经是128mEclipse已经是128m了),就改成 256m。我一般在服务器上为安全起见,改成256m。

   java.lang.OutOfMemoryErrorheap space或其它OutOfMemoryError,这个异常实际上跟上面的异常是一个异常,但解决方法不同,所以分开来写。上面那个异常是因为JVMperm存区分少了引起的(JVM的存区分为 young,old,perm三种)。而这个异常是因为JVM堆存或者说总体分少了。解决方法是更改 -Xms -Xmx 启动参数,通常是扩大1倍。xms是管理启动时最小存量的,xmx是管里JVM最大的存量的。

    java.lang.StackOverflowError:每个线程都有他自己的StackStack用于管理线程占用的内存资源。stack分区不能动态扩展,或不足以生成新的线程。几种境况可能抛出这个异常,一个是Stacks里的线程超过允许的时候,另一个是当native method要求更大的存,而超过native method允许的存的时候。根据SUN的文档,提高-XX:ThreadStackSize=512的值。

 

源文档 <http://blog.sina.com.cn/s/blog_6c663fa50100qf1c.html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值