「jvm」Tomcat中JVM内存溢出及合理配置( 三 )


3. 查看JVM内存信息
Runtime.getRuntime().maxMemory(); //最大可用内存 , 对应-Xmx
Runtime.getRuntime().freeMemory(); //当前JVM空闲内存
Runtime.getRuntime().totalMemory(); //当前JVM占用的内存总数 , 其值相当于当前JVM已使用的内存及freeMemory()的总和
关于maxMemory() , freeMemory()和totalMemory():maxMemory()为JVM的最大可用内存 , 可通过-Xmx设置 , 默认值为物理内存的1/4 , 设置不能高于计算机物理内存; totalMemory()为当前JVM占用的内存总数 , 其值相当于当前JVM已使用的内存及freeMemory()的总和 , 会随着JVM使用内存的增加而增加; freeMemory()为当前JVM空闲内存 , 因为JVM只有在需要内存时才占用物理内存使用 , 所以freeMemory()的值一般情况下都很小 , 而JVM实际可用内存并不等于freeMemory() , 而应该等于maxMemory()-totalMemory()+freeMemory() 。
4. 实例 , 以下给出1G内存环境下java jvm 的参数设置参考
JAVA_OPTS=\"-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true \"
大型的web工程 , 用tomcat默认分配的内存空间无法启动 , 如果不是在myeclipse中启动tomcat可以对tomcat这样设置:
TOMCAT_HOME\\bin\\catalina.bat 中添加这样一句话:
set JAVA_OPTS= -Xmx1024M -Xms512M -XX:MaxPermSize=256m
如果要在myeclipse中启动 , 上述的修改就不起作用了 , 可如下设置:
Myeclipse->preferences->myeclipse->servers->tomcat->tomcat×.×->JDK面板中的
Optional Java VM arguments中添加:-Xmx1024M -Xms512M -XX:MaxPermSize=256m
对于单独的.class , 可以用下面的方法对Test运行时的jvm内存进行设置 。java -Xms64m -Xmx256m Test -Xms是设置内存初始化的大小 -Xmx是设置最大能够使用内存的大小 。
四、JVM内存配置与GC
需要考虑的是Java提供的垃圾回收机制 。 JVM的堆大小决定了JVM花费在收集垃圾上的时间和频度 。 收集垃圾可以接受的速度与应用有关 , 应该通过分析实际的垃圾收集的时间和频率来调整 。 如果堆的大小很大 , 那么完全垃圾收集就会很慢 , 但是频度会降低 。 如果你把堆的大小和内存的需要一致 , 完全收集就很快 , 但是会更加频繁 。 调整堆大小的的目的是最小化垃圾收集的时间 , 以在特定的时间内最大化处理客户的请求 。 在基准测试的时候 , 为保证最好的性能 , 要把堆的大小设大 , 保证垃圾收集不在整个基准测试的过程中出现 。 如果系统花费很多的时间收集垃圾 , 请减小堆大小 。 一次完全的垃圾收集应该不超过 3-5 秒 。 如果垃圾收集成为瓶颈 , 那么需要指定堆的大小 , 检查垃圾收集的详细输出 , 研究垃圾收集参数对性能的影响 。 一般说来 , 你应该使用物理内存的 80% 作为堆大小 。 当增加处理器时 , 记得增加内存 , 因为分配可以并行进行 , 而垃圾收集不是并行的 。
Java Heap分为3个区:
1.Young 2.Old 3.Permanent 。 Young保存刚实例化的对象 。 当该区被填满时 , GC会将对象移到Old区 。 Permanent区则负责保存反射对象 , 本文不讨论该区 。
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值都很小 。