湖北省疾病预防控制中心官方网站,asp网站500错误iis7,西安发布最新通知,网站建设与管理的发展常见的JVM参数配置
垃圾回收统计信息 -XX:PrintGC 打印GC简要信息 -XX:PrintGCDetails打印GC的详细信息 -XX:PrintGCTimeStamps打印CG发生的时间戳 -Xloggc:log/gc.log 指定GC log的位置#xff0c;以文件输出 -XX:PrintHeapAtGC 每一次GC前和GC后#xff0c;都打印堆信…常见的JVM参数配置
垃圾回收统计信息 -XX:PrintGC 打印GC简要信息 -XX:PrintGCDetails打印GC的详细信息 -XX:PrintGCTimeStamps打印CG发生的时间戳 -Xloggc:log/gc.log 指定GC log的位置以文件输出 -XX:PrintHeapAtGC 每一次GC前和GC后都打印堆信息。 堆设置 -Xms初始堆大最小堆 -Xmx最大堆大小 -Xmn设置新生代的大小 -XX:NewRatio新生代和年老代的比值如为3表示年轻代与年老代比值为13年轻代占整个年轻代年老代之和的1/4 -XX:SurvivorRatio设置两个Survivor区和eden的比值。注意Survivor区有两个。如8表示EdenSurvivor82一个Survivor区占整个年轻代的1/10 -XX:PermSize设置永久区的初始空间 -XX:MaxPermSize设置永久区的最大空间。 -XX:MaxTenuringThreshold10新生代垃圾的最大年龄代表对象在Survivor区经过10次复制以后才进入老年代。如果设置为0则年轻代对象不经过Survivor区直接进入老年代。 -XX:PretenureSizeThreshold设置大对象直接进入老年代的阈值。当对象的大小超过这个值时将直接在老年代分配。 栈的分配参数 -Xss设置栈空间的大小 垃圾收集器设置
串行收集器的设置 -XX:UseSerialGC:设置串行收集器一般适用于小型应用和单处理器算法比较简单GC效率也较高但可能会给应用带来停顿。 并行回收收集器设置(ParallelGC收集器的目标是达到一个可控制的吞吐量) -XX:UseParNewGC设置年轻代为并行收集。 -XX:UseParallelGC:设置年轻代使用并行回收收集器。多个线程并行执行GC一般适用于多处理器系统中可以提高GC的效率但算法复杂系统消耗较大。 -XX:UseParalledlOldGC:设置老年代为并行回收收集器Java1.6之后才出现。 -XX:ParallelGCThreadsn:设置并行收集器收集时使用的线程数最好与CPU数目相等。 -XX:MaxGCPauseMillisn:设置年轻代每次并行垃圾回收的最大暂停时间。 -XX:GCTimeRation:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1n) -XX:UseAdaptiveSizePolicy自适应策略自动选择年轻代区大小和相应的Survivor区比例。 CMS并发收集器(以最短停顿为目标) -XX:UseConcMarkSweepGC使用CMS内存收集。 -XX:ParallelCMSThreads: 设定 CMS 的线程数量。 -XX:CMSFullGCsBeforeCompactionCMS多少次后进行内存压缩由于并发收集器不对内存空间进行压缩整理所以运行一段时间以后会产生碎片,使得运行效率降低。 -XX:UseCMSCompactAtFullCollection在FULL GC的时候对年老代的压缩。CMS是不会移动内存的因此这个非常容易产生碎片导致内存不够用因此内存的压缩这个时候就会被启用。可能会影响性能,但是可以消除碎片。 -XX:CMSInitiatingOccupancyFraction:设置 CMS 收集器在老年代空间被使用多少后触发默认为 68%。 -XX:CMSClassUnloadingEnabled:允许对类元数据进行回收。 -XX:CMSParallelRemarkEndable:启用并行重标记。 -XX:CMSInitatingPermOccupancyFraction:当永久区占用率达到这一百分比后启动 CMS 回收 (前提是-XX:CMSClassUnloadingEnabled 激活了)。 -XX:UseCMSInitatingOccupancyOnly:表示只在到达阈值的时候才进行 CMS 回收。 -XX:CMSIncrementalMode:使用增量模式比较适合单 CPU。 G1收集器 -XX:UseG1GC使用 G1 回收器。 -XX:UnlockExperimentalVMOptions:允许使用实验性参数。 -XX:MaxGCPauseMills:设置最大垃圾收集停顿时间。 -XX:GCPauseIntervalMills:设置停顿间隔时间。 JVM的GC性能优化
对于GC的性能主要有2个方面的指标吞吐量(工作时间不算gc的时间占总的时间比)和暂停时间。
堆大小
默认情况下vm会增加/减少heap大小以维持free space在整个vm中占的比例这个比例由MinHeapFreeRatio和MaxHeapFreeRatio指定。
一般而言server端的app会有以下规则
1对vm分配尽可能多的内存 2将Xms和Xmx设为一样的值。如果虚拟机启动时设置使用的内存比较小这个时候又需要初始化很多对象虚拟机就必须重复地增加内存。 3处理器核数增加内存也跟着增大。
年轻代
1对于程序流畅性运行影响的因素是新生代的大小。新生代越大minor collection越少但是在堆大小固定情况下新生代越大就意味着越小的老年代就意味着更多的major collection。 28NewRatio反映的是新生代和老年代的大小比例。NewSize和MaxNewSize反映的是young generation大小的下限和上限将这两个值设为一样就固定了young generation的大小同Xms和Xmx设为一样。 3SurvivorRatio也可以优化survivor的大小不过这对于性能的影响不是很大。SurvivorRatio是Eden和Survior大小比例。
一般而言server端的app会有以下规则
1首先决定能分配给vm的最大的堆大小然后设定最佳的young generation的大小 2如果堆大小固定后增加新生代的大小意味着减小老年代大小。让老年代在任何时候够大能够容纳所有存活的对象留10%-20%的空余。
年轻代大小选择
1响应时间优先的应用尽可能设大直到接近系统的最低响应时间限制在此种情况下年轻代收集发生的频率也是最小的同时,减少到达年老代的对象。 2吞吐量优先的应用尽可能的设置大可能到达Gbit的程度因为对响应时间没有要求垃圾收集可以并行进行一般适合8CPU以上的应用。 3避免设置过小。当新生代设置过小时会导致①YGC次数更加频繁②可能导致YGC对象直接进入旧生代如果此时旧生代满了会触发FGC。
老年代大小选择
1响应时间优先的应用年老代使用并发收集器。如果堆设置小了可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式如果堆大了则需要较长的收集时间。一般需要参考以下数据 并发垃圾收集信息、持久代并发收集次数、传统GC信息、花在年轻代和年老代回收上的时间比例。 2吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代这样可以尽可能回收掉大部分短期对象减少中期的对象而年老代尽存放长期存活对象。
较小堆引起的碎片问题
因为CMS年老代的并发收集器使用标记清除算法所以不会对堆进行压缩。当收集器回收时它会把相邻的空间进行合并,这样可以分配给较大的对象。但是当堆空间较小时运行一段时间以后就会出现碎片如果并发收集器找不到足够的空间那么并发收集器将会停止可能需要进行如下配置 -XX:UseCMSCompactAtFullCollection使用并发收集器时开启对年老代的压缩。 -XX:CMSFullGCsBeforeCompaction0上面配置开启的情况下这里设置多少次Full GC后对年老代进行压缩。 其他说明
1用64位操作系统Linux下64位的jdk比32位jdk要慢一些但是吃得内存更多吞吐量更大
2XMX和XMS设置一样大MaxPermSize和MinPermSize设置一样大这样可以减轻伸缩堆大小带来的压力
3CMS的目标是最短的GC停顿时间使用CMS的好处是用尽量少的新生代然后老生代利用CMS并行收集这样能保证系统低延迟的吞吐效率
4系统停顿的时候可能是GC的问题也可能是程序的问题多用jmap和jstack查看或者killall -3 java然后查看java控制台日志能看出很多问题
5如果用了缓存那么年老代应该大一些缓存的HashMap不应该无限制长建议采用LRU算法的Map做缓存LRUMap的最大长度也要根据实际情况设定
6采用并发回收时年轻代小一点年老代要大因为年老代用的是并发回收即使时间长点也不会影响其他程序继续运行网站不会停顿
7JVM参数的设置(特别是 –Xmx –Xms –Xmn -XX:SurvivorRatio -XX:MaxTenuringThreshold等参数的设置)没有一个固定的公式需要根据PV old区实际数据、YGC次数等多方面来衡量。为了避免promotion faild可能会导致xmn设置偏小也意味着YGC的次数会增多处理并发访问的能力下降等问题。每个参数的调整都需要经过详细的性能测试才能找到特定应用的最佳配置。
promotion failed:晋升失败
垃圾回收时promotion failed一般可能是两种原因产生第一个原因是To survivor救助空间不够救助空间里的对象还不应该被移动到年老代但年轻代又有很多对象需要放入救助空间第二个原因是年老代没有足够的空间接纳来自年轻代的对象这两种情况都会转向Full GC网站停顿时间较长。
解决方案
第一个原因解决办法是去掉救助空间设置-XX:SurvivorRatio65536 -XX:MaxTenuringThreshold0即可但是因为没有用到救助空间所以年老代容易满Full GC执行会比较频繁所以可以把救助空间加大这样也不会有promotion failed。第二个原因我的解决办法是设置CMSInitiatingOccupancyFraction为某个值假设70这样年老代空间到70%时就开始执行CMS年老代有足够的空间接纳来自年轻代的对象。
实际编程中的性能优化
下面是一些在实际写程序的过程中应该注意的点养成这些习惯可以在一定程度上减少内存的无谓消耗进一步就可以减少因为内存不足导致GC不断。
1减少new对象。每次new对象之后都要开辟新的内存空间。这些对象不被引用之后还要回收掉。因此如果最大限度地合理重用对象或者使用基本数据类型替代对象都有助于节省内存 2多使用局部变量减少使用静态变量。局部变量被创建在栈中存取速度快。静态变量则是在堆内存 3避免使用finalize该方法会给GC增添很大的负担 4如果是单线程尽量使用非多线程安全的因为线程安全来自于同步机制同步机制会降低性能。例如单线程程序能使用HashMap就不要用HashTable。同理尽量减少使用synchronized 5用移位符号替代乘除号。ega*8应该写作a3 6对于经常反复使用的对象使用缓存 7尽量使用基本类型而不是包装类型尽量使用一维数组而不是二维数组 8尽量使用final修饰符final表示不可修改访问效率高 9单线程情况下或者是针对于局部变量字符串尽量使用StringBuilder比StringBuffer要快 10String为什么慢因为String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象然后将指针指向新的 String 对象。如果不能保证线程安全尽量使用StringBuffer来连接字符串。这里需要注意的是StringBuffer的默认缓存容量是16个字符如果超过16apend方法调用私有的expandCapacity()方法来保证足够的缓存容量。因此如果可以预设StringBuffer的容量避免append再去扩展容量。如果可以保证线程安全就是用StringBuilder。