众所周知jvm的内存是受限的一为机器的体系架构二为操作系统本身
xxSPARC的内存映射是不同而各操作系统的内存管理机制也有区别
以下是来自;
Heap设定与垃圾回收Java Heap分为个区YoungOld和PermanentYoung保存刚实例化的对象当该区被填满时GC会将对象移到Old区Permanent区则负责保存反射对象本文不讨论该区JVM的Heap分配可以使用X参数设定
Xms
初始Heap大小
Xmx
java heap最大值
Xmn
young generation的heap大小
JVM有个GC线程第一个线程负责回收Heap的Young区第二个线程在Heap不足时遍历Heap将Young 区升级为Older区Older区的大小等于Xmx减去Xmn不能将Xms的值设的过大因为第二个线程被迫运行会降低JVM的性能
为什么一些程序频繁发生GC?有如下原因
l 程序内调用了Systemgc()或Runtimegc()
l 一些中间件软件调用自己的GC方法此时需要设置参数禁止这些GC
l Java的Heap太小一般默认的Heap值都很小
l 频繁实例化对象Release对象此时尽量保存并重用对象例如使用StringBuffer()和String()
如果你发现每次GC后Heap的剩余空间会是总空间的%这表示你的Heap处于健康状态许多Server端的Java程序每次GC后最好能有%的剩余空间经验之谈
.Server端JVM最好将Xms和Xmx设为相同值为了优化GC最好让Xmn值约等于Xmx的/[]
.一个GUI程序最好是每到秒间运行一次GC每次在半秒之内完成[]
注意
.增加Heap的大小虽然会降低GC的频率但也增加了每次GC的时间并且GC运行时所有的用户线程将暂停也就是GC期间Java应用程序不做任何工作
.Heap大小并不决定进程的内存使用量进程的内存使用量要大于Xmx定义的值因为Java为其他任务分配内存例如每个线程的Stack等
.Stack的设定
每个线程都有他自己的Stack
Xss
每个线程的Stack大小
Stack的大小限制着线程的数量如果Stack过大就好导致内存溢漏Xss参数决定Stack大小例如XssK如果Stack太小也会导致Stack溢漏
.硬件环境
硬件环境也影响GC的效率例如机器的种类内存swap空间和CPU的数量
如果你的程序需要频繁创建很多transient对象会导致JVM频繁GC这种情况你可以增加机器的内存来减少Swap空间的使用[]
.种GC
第一种为单线程GC也是默认的GC该GC适用于单CPU机器
第二种为Throughput GC是多线程的GC适用于多CPU使用大量线程的程序第二种GC与第一种GC相似不同在于GC在收集Young区是多线程的但在Old区和第一种一样仍然采用单线程XX:+UseParallelGC参数启动该GC
第三种为Concurrent Low Pause GC类似于第一种适用于多CPU并要求缩短因GC造成程序停滞的时间这种GC可以在Old区的回收同时运行应用程序XX:+UseConcMarkSweepGC参数启动该GC
第四种为Incremental Low Pause GC适用于要求缩短因GC造成程序停滞的时间这种GC可以在Young区回收的同时回收一部分Old区对象Xincgc参数启动该GC