为什么80%的码农都做不了架构师?>>>
broker的jvm参数分析(rocketmq地址)
-
rocketmq的broker.sh中的jvm参数。
# JVM Configuration
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8 -XX:+DisableExplicitGC"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch"
JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib"
#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
分析
-
1.内存大小设置
-Xmx:设置JVM最大可用内存.
-Xms:设置JVM初始内存.此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存.
-Xmn:设置年轻代大小.
-
2.GC回收设置
-XX:+UseG1GC 使用G1垃圾回收器
-XX:G1HeapRegionSize=16m 设置的 G1 区域的大小。值是 2 的幂,范围是 1 MB 到 32 MB 之间。目标是根据最小的 Java 堆大小划分出约 2048 个区域。
-XX:G1ReservePercent=25 设置作为空闲空间的预留内存百分比,以降低目标空间溢出的风险。默认值是 10%。增加或减少百分比时,请确保对总的 Java 堆调整相同的量。Java HotSpot VM build 23 中没有此设置。
-XX:InitiatingHeapOccupancyPercent=30 设置触发标记周期的 Java 堆占用率阈值。默认占用率是整个 Java 堆的 45%。
-XX:SoftRefLRUPolicyMSPerMB=0 这个参数比较有用的,官方解释是:Soft reference在虚拟机中比在客户集中存活的更长一些。其清除频率可以用命令行参数 -XX:SoftRefLRUPolicyMSPerMB=
-XX:SurvivorRatio=8 两个survivor:eden=2:8,就是一个survivor占eden的十分之一。
-XX:+DisableExplicitGC 标志自动将System.gc()调用转换成一个空操作,就是应用中调用System.gc()会变成一个空操作。
-
3.日志设置
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" 不作详细介绍
-XX:-OmitStackTraceInFastThrow
强制要求JVM始终抛出含堆栈的异常(-XX:-OmitStackTraceInFastThrow)
它跟JDK5的一个新特性有关,对于一些频繁抛出的异常,JDK为了性能会做一个优化,即JIT重新编译后会抛出没有堆栈的异常,而在使用-server模式时,该优化选项是开启的,因此在频繁抛出某个异常一段时间后,该优化开始起作用,即只抛出没有堆栈的异常信息
-
4.初始化设置
-XX:+AlwaysPreTouch
启动时访问并置零内存页面-XX:+AlwaysPreTouch
启动时就把参数里说好了的内存全部舔一遍,可能令得启动时慢上一点,但后面访问时会更流畅,比如页面会连续分配,比如不会在晋升新生代到老生代时才去申请页面使得GC停顿时间加长。不过这选项对32G之类的大堆才会更有感觉一点。
-
5.直接内存设置
-XX:MaxDirectMemorySize=15g 直接内存大小,因为使用netty作为tcp框架,netty使用的内存不经过jvm管理。
-
6.内存页面
-XX:-UseLargePages 大页面
在计算机系统中,内存被分为固定大小的区块,这个区块就叫做页(page)。内存的存取是通过程序把虚拟内存地址转换成物理内存地址实现的。虚拟到物理地址是在一个块表里面映射的。为了减少每次存取内存的时候使用页表的消耗,通常会使用一种快速的虚拟到物理地址转换的缓存。这个缓存叫做转换后备缓冲区(translation lookaside buffer),简称TLB。
通过TLB来满足虚拟到物理地址的映射请求,会比遍历页表来找到映射关系快很多,一个TLB通常包含指定数量的条目。一个TLB条目是一个基于页大小虚拟到物理地址映射,因此,更大的页大小允许一个条目或者一个TLB有更大的内存地址范围。在TLB中有更广泛的地址,更少的地址转换请求在TLB中不命中,就可以减少遍历页表(page table)操作。使用大页的目的就是减少TLB的不命中。
Oracle solariz,Linux 以及Windows都支持HotSpot VM使用大页。通常处理器可以支持几种页大小,不过不同的处理器各不相同。另外,操作系统配置需要使用大页。下面说说怎么样在Linux下使用大页(Large Page)
Linux下的大页面
在写作本书的时候,在Linux下使用大页,除使用-XX:+UseLargePages命令选项以外,需要修改操作系统配置。Linux的修改操作具体和发行版本以及内核有关系。为了合理的启用Linux下的大页,可以征询Linux管理员的意见或者阅读Linux发行文档。一旦使用了Linux操作系统配置已经修改,-XX:+UseLargePage命令行选项就必须要使用了。比如:
1. $ java -server -Xmx1024m -Xms1024m -Xmn256m -XX:+UseLargePages ...
如果大页没有被合理设置,HotSpot VM同样会接受-XX:+UseLargePages是一个有效的选项,不过会报告无法获取大页,而且会退回操作系统的默认页大小。
-
7.线程优化
-XX:-UseBiasedLocking
有偏见的锁
有偏见的锁是使得锁更偏爱上次使用到它线程。在非竞争锁的场景下,即只有一个线程会锁定对象,可以实现近乎无锁的开销。
有偏见的锁,是在Java 5 update 6引入的。通过HotSpot VM的命令选项-XX:+UseBiasedLocking启用。
Java 5 HotSpot JDK需要明确的命令来启用这个特性,在使用-XX:+AggressiveOpts选项,有偏见的锁会Java 5中会被自动启用。在Java 6中是默认启用的。
各种经历告诉我们这个特性对大多数应用还是非常有用的。然后,有一些应用使用这个属性不一定能够表现的很好,比如,锁被通常不被上次使用它的同一个线程使用。对于Java应用来说,由于stop-the-world安全点操作需要取消偏见,这样可以通过使用-XX:-UseBiaseLocking来获得好处。如果你不清楚你的应用是什么情况,可以通过分别设置这两个选项来测试。
-
推导
broker特点:1线程不多,追求吞吐量,追求低延时,数据量大。
broker的作用是,接收生产者的消息,保存和分发消息给消费者。
broker工作,使用tcp长链接,使用大量内存作为缓冲,然后还有大量数据。有偏向锁,在少线程情况下(broker就是线程少,要求吞吐量大),就是非公平锁那样,会比公平锁线程切换少,吞吐量大,(注意,线程多就不要这样设置了)。在大量对象创建和销毁,g1堆被划分成 许多个连续的区域(region),这样的机制在内存产生碎片时,更加高效,详细请阅读g1的文章。
server的jvm参数分析
# JVM Configuration
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g -XX:PermSize=128m -XX:MaxPermSize=320m"
JAVA_OPT="${JAVA_OPT}
-XX:+UseConcMarkSweepGC 对老年代使用并发标记扫描收集。
-XX:+UseCMSCompactAtFullCollection 对老年代使用并发回收。
-XX:CMSInitiatingOccupancyFraction=70 默认CMS是在tenured generation沾满70%(默认68%)的时候开始进行CMS收集
-XX:+CMSParallelRemarkEnabled 为了减少第二次暂停的时间,开启并行remark
-XX:SoftRefLRUPolicyMSPerMB=0
-XX:+CMSClassUnloadingEnabled 相对于并行收集器,CMS收集器默认不会对永久代进行垃圾回收。如果希望对永久代进行垃圾回收,可用设置标志-XX:+CMSClassUnloadingEnabled。
-XX:SurvivorRatio=8
-XX:+DisableExplicitGC
-XX:-UseParNewGC"
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails"
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/lib"
#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"
-
推导
nameserver的对象没有broker的对象那么活跃,因为在mq中,nameserver的作用只是作为broker的地址信息传递,不象broker有不断的消息进来,和传送。可见采用cms收集器足以,优化一下,减少stop-the-world的时间。
-
资料来源
http://www.importnew.com/11336.html
http://blog.csdn.net/zhoutao198712/article/details/7842659
http://www.blogjava.net/killme2008/archive/2009/09/22/295931.html
http://ifeve.com/useful-jvm-flags-part-7-cms-collector/
http://www.oracle.com/technetwork/cn/articles/java/g1gc-1984535-zhs.html
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html