这两天看到下面这篇文章的图不错。
一图读懂JVM架构解析
其中最上一层是Nursery内存,一个对象被创建以后首先被放到Nursery中的Eden内 存中,如果存活期超两个Survivor之后就会被转移到长时内存中(Old Generation)中。
永久内存中存放着对象的方法、变量等元数据信息。通过如果永久内存不够,就会得到如下错误:
Java.lang.OutOfMemoryError: PermGen 1 1
JDK8中把存放元数据中的永久内存从堆内存中移到了本地内存(native memory)中,这样永久内存就不再占用堆内存,它可以通过自动增长来避免JDK7以及前期版本中常见的永久内存错误(Java.lang.OutOfMemoryError: PermGen)。
JDK8也提供了一个新的设置Matespace内存大小的参数:
-XX:MaxMetaspaceSize=128m 1 1注意:如果不设置JVM将会根据一定的策略自动增加本地元内存空间。如果你设置的元内存空间过小,你的应用程序可能得到以下错误:
java.lang.OutOfMemoryError: Metadata space 1 1-XX 参数被称为不稳定参数,此类参数的设置很容易引起JVM性能上的差异。
不稳定参数语法规则:
布尔类型
-XX:+<option> '+'表示启用该选项 -XX:-<option> '-'表示关闭该选项 12 12数字类型
-XX:<option>=<number> # 可跟随单位,例如:'m'或'M'表示兆字节;'k'或'K'千字节;'g'或'G'千兆字节。32K与32768是相同大小的。 12345 12345字符串类型
-XX:<option>=<string> # 通常用于指定一个文件、路径或一系列命令列表。例如:-XX:HeapDumpPath=./dump.core 12345 12345特点
它仅仅使用单线程进行垃圾回收它是独占式的垃圾回收进行垃圾回收时, Java应用程序中的线程都需要暂停(Stop-The-World)使用复制算法适合CPU等硬件不是很好的场合设置参数
-XX:+UseSerialGC 指定新生使用新生代串行收集器和老年代串行收集器, 当以client模式运行时, 它是默认的垃圾收集器 1 1特点
同新生代串行回收器一样, 单线程, 独占式的垃圾回收器通常老年代垃圾回收比新生代回收要更长时间, 所以可能会使应用程序停顿较长时间设置参数
-XX:+UseSerialGC 新生代, 老年代都使用串行回收器 -XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器 -XX:+UseParallelGC 新生代使用ParallelGC回收器, 老年代使用串行回收器 123 123特点
将串行回收多线程化使用复制算法垃圾回收时, 应用程序仍会暂停, 只不过由于是多线程回收, 在多核CPU上,回收效率会高于串行回收器, 反之在单核CPU, 效率会不如串行回收器设置参数
-XX:+UseParNewGC 新生代使用ParNew回收器, 老年代使用串行回收器 -XX:+UseConcMarkSweepGC 新生代使用ParNew回收器, 老年代使用CMS回收器 -XX:ParallelGCThreads=n 指回ParNew回收器工作时的线程数量, cpu核数小时8时, 其值等于cpu数量, 高于8时,可以使用公式(3+((5*CPU_count)/8)) 123 123特点
同ParNew回收器一样, 不同的地方在于,它非常关注系统的吞吐量(通过参数控制)使用复制算法支持自适应的GC调节策略设置参数
-XX:+UseParallelGC 新生代用ParallelGC回收器, 老年代使用串行回收器 -XX:+UseParallelOldGC 新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器系统吞吐量的控制: -XX:MaxGCPauseMillis=n(单位ms) 设置垃圾回收的最大停顿时间, -XX:GCTimeRatio=n(n在0-100之间) 设置吞吐量的大小, 假设值为n, 那系统将花费不超过1/(n+1)的时间用于垃圾回收 -XX:+UseAdaptiveSizePolicy 打开自适应GC策略, 在这种模式下, 新生代的大小, eden,survivior的比例, 晋升老年代的对象年龄等参数会被自动调整,以达到堆大小, 吞吐量, 停顿时间之间的平衡点 12345 12345特点
同新生代的ParallelGC回收器一样, 是属于老年代的关注吞吐量的多线程并发回收器使用标记压缩算法设置参数
-XX:+UseParallelOldGC 新生代用ParallelGC回收器, 老年代使用ParallelOldGC回收器, 是非常关注系统吞吐量的回收器组合, 适合用于对吞吐量要求较高的系统 -XX:ParallelGCThreads=n 指回ParNew回收器工作时的线程数量, cpu核数小时8时, 其值等于cpu数量, 高于8时, 可以使用公式(3+((5*CPU_count)/8)) 12 12特点
是并发回收, 非独占式的回收器, 大部分时候应用程序不会停止运行针对年老代的回收器使用并发标记清除算法, 因此回收后会有内存碎片, 可以使参数设置进行内存碎片的压缩整理与ParallelGC和ParallelOldGC不同, CMS主要关注系统停顿时间主要步骤
初始标记并发标记预清理重新标记并发清理并发重置注:初始标记与重新标记是独占系统资源的,不能与用户线程一起执行,而其它阶段则可以与用户线程一起执行
设置参数
-XX:-CMSPrecleaningEnabled 关闭预清理, 不进行预清理, 默认在并发标记后, 会有一个预清理的操作,可减少停顿时间 -XX:+UseConcMarkSweepGC 老年代使用CMS回收器, 新生代使用ParNew回收器 -XX:ConcGCThreads=n 设置并发线程数量, -XX:ParallelCMSThreads=n 同上, 设置并发线程数量, -XX:CMSInitiatingOccupancyFraction=n 指定老年代回收阀值, 即当老年代内存使用率达到这个值时, 会执行一次CMS回收,默认值为68, 设置技巧: (Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100)>=Xmn -XX:+UseCMSCompactAtFullCollection 开启内存碎片的整理, 即当CMS垃圾回收完成后, 进行一次内存碎片整理, 要注意内存碎片的整理并不是并发进行的, 因此可能会引起程序停顿 -XX:CMSFullGCsBeforeCompation=n 用于指定进行多少次CMS回收后, 再进行一次内存压缩 -XX:+CMSParallelRemarkEnabled 在使用UseParNewGC 的情况下, 尽量减少 mark 的时间 -XX:+UseCMSInitiatingOccupancyOnly 表示只有达到阀值时才进行CMS回收 -XX:+CMSConcurrentMTEnabled 当该标志被启用时,并发的CMS阶段将以多线程执行,默认开启 -XX:+CMSIncrementalMode 在增量模式下,CMS 收集器在并发阶段,不会独占整个周期, 而会周期性的暂停,唤醒应用线程。收集器把并发阶段工作,划分为片段,安排在次级(minor) 回收之间运行。这对需要低延迟,运行在少量CPU服务器上的应用很有用。 123456789101112 123456789101112设置参数
-XX:+CMSClassUnloadingEnabled 开启回收Perm区的内存, 默认情况下, 是需要触发一次FullGC -XX:CMSInitiatingPermOccupancyFraction=n 当永久区占用率达到这个n值时,启动CMS回收, 需上一个参数开启的情况下使用 12 12特点
独特的垃圾回收策略, 属于分代垃圾回收器使用分区算法, 不要求eden, 年轻代或老年代的空间都连续并行性: 回收期间, 可由多个线程同时工作, 有效利用多核cpu资源并发性: 与应用程序可交替执行, 部分工作可以和应用程序同时执行分代GC: 分代收集器, 同时兼顾年轻代和老年代空间整理: 回收过程中, 会进行适当对象移动, 减少空间碎片可预见性: G1可选取部分区域进行回收, 可以缩小回收范围, 减少全局停顿主要步骤
新生代GC并发标记周期
初始标记新生代GC(此时是并行, 应用程序会暂停止)–>根区域扫描–>并发标记–>重新标记(此时是并行, 应用程序会暂停止)–>独占清理(此时应用程序会暂停止)–>并发清理
混合回收
这个阶段即会执行正常的年轻代gc, 也会选取一些被标记的老年代区域进行回收, 同时处理新生代和年老轻
若需要, 会进行FullGC
混合GC时发生空间不足 在新生代GC时, survivor区和老年代无法容纳幸存对象时 以上两者都会导致一次FullGC产生
设置参数
-XX:+UseG1GC 打开G1收集器开关, -XX:MaxGCPauseMillis=n 指定目标的最大停顿时间,任何一次停顿时间超过这个值, G1就会尝试调整新生代和老年代的比例, 调整堆大小, 调整晋升年龄 -XX:ParallelGCThreads=n 用于设置并行回收时, GC的工作线程数量 -XX:InitiatingHeapOccpancyPercent=n 指定整个堆的使用率达到多少时, 执行一次并发标记周期, 默认45, 过大会导致并发标记周期迟迟不能启动, 增加FullGC的可能, 过小会导致GC频繁, 会导致应用程序性能有所下降 1234 1234System.gc()
(1)禁用System.gc() -XX:+DisableExplicitGC 禁止程序中调用System.gc(), 加了此参数, 程序若有调用, 返回的空函数调用 System.gc()的调用, 会使用FullGC的方式回收整个堆而会忽略CMS或G1等相关回收器 (2)System.gc()使用并发回收 -XX:+ExplicitGCCinvokesConcurrent 使用并发方式处理显示的gc, 即开启后, System.gc()这种显示GC才会并发的回收, (CMS, G1) 12345 12345并行GC前额外触发的新生代GC
(1)使用并行回收器(UseParallelGC或者UseParallelOldGC)时, 会额外先触发一个新生代GC, 目的是尽可能减少停顿时间 (2)若不需要这种特性, 可以使用以下参数去除 -XX:-ScavengeBeforeFullGC 即去除在FullGC之前的那次新生代GC, 原本默认值为true 123 123对象何时进入老年代
(1)当对象首次创建时, 会放在新生代的eden区, 若没有GC的介入,会一直在eden区, GC后,是可能进入survivor区或者年老代 (2)当对象年龄达到一定的大小 ,就会离开年轻代, 进入老年代, 对象进入老年代的事件称为晋升, 而对象的年龄是由GC的次数决定的, 每一次GC,若对象没有被回收, 则对象的年龄就会加1, 可以使用以下参数来控制新生代对象的最大年龄: -XX:MaxTenuringThreshold=n 假设值为n , 则新生代的对象最多经历n次GC, 就能晋升到老年代, 但这个必不是晋升的必要条件 -XX:TargetSurvivorRatio=n 用于设置Survivor区的目标使用率,即当survivor区GC后使用率超过这个值, 就可能会使用较小的年龄作为晋升年龄 (3)除年龄外, 对象体积也会影响对象的晋升的, 若对象体积太大, 新生代无法容纳这个对象, 则这个对象可能就会直接晋升至老年代, 可通过以下参数使用对象直接晋升至老年代的阈值, 单位是byte -XX:PretenureSizeThreshold 即对象的大小大于此值, 就会绕过新生代, 直接在老年代分配, 此参数只对串行回收器以及ParNew回收有效, 而对ParallelGC回收器无效 123456 123456在TLAB上分配对象(Thread Local Allocation Buffer, 线程本地分配缓存)
(1)TLAB: TLAB是一个线程专用的内存分配区域, 虚拟机为线程分配空间, 针对于体积不大的对象, 会优先使用TLAB, 这个可以加速对象的分配, TLAB是默认开启的, 若要关闭可以使用以下参数关闭 -XX:-UseTLAB 关闭TLAB -XX:+UseTLAB 开启TLAB, 默认也是开启的 -XX:+PrintTLAB 观察TALB的使用情况 -XX:TLABRefillWasteFraction=n 设置一个比率n, 而refill_waste的值就是(TLAB_SIZE/n), 即TLAB空间较小, 大对象无法分配在TLAB,所以会直接分配到堆上,TLAB较小也很容易装满, 因此当TLAB的空间不够分配一个新对象, 就会考虑废弃当前TLAB空间还是直接分配到堆上, 就会使用此参数进行判断, 小于refill_waste就允许废弃, 而新建TLAB来分配对象,而大于refill_waste就直接在堆上分配, 默认是64 -XX:+ResizeTLAB 开启TLAB自动调整大小, 默认是开启的, 若要关闭把+号换成-号即可 -XX:TLABSize=n 设置一个TLAB的大小, 前提先关闭TLAB的自动调整 1234567 1234567主要用来输出JVM中运行的进程状态信息。语法格式如下:
jps [options] [hostid] # hostid语法如下: [protocol:][[//]hostname][:port][/servername] protocol - 如果protocol及hostname都没有指定,那表示的是与当前环境相关的本地协议,如果指定了hostname却没有指定protocol,那么protocol的默认就是rmi。 hostname - 服务器的IP或者名称,没有指定则表示本机。 port - 远程rmi的端口,如果没有指定则默认为1099。 Servername - 注册到RMI注册中心中的jstatd的名称。 # 如果不指定hostid就默认为当前主机或服务器。 # 命令行参数选项 -q 忽略输出类名、Jar名和传入main方法的参数 -m 输出传入main方法的参数 -l 输出main类或Jar的全限名 -v 输出传入JVM的参数 -V 输出通过标记的文件传递给JVM的参数(.hotspotrc文件,或者是通过参数-XX:Flags=<filename>指定的文件) -J 用于传递jvm选项到由javac调用的java加载器中,例如,“-J-Xms48m”将把启动内存设置为48M,使用-J选项可以非常方便的向基于Java的开发的底层虚拟机应用程序传递参数。 123456789101112131415161718 123456789101112131415161718主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
jstack [option] pid jstack [option] executable core jstack [option] [server-id@]remote-hostname-or-ip # 命令行参数选项说明如下: -l 长列表,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况 -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法) -F 当’jstack [-l] pid’没有相应的时候强制打印栈信息 -h | -help打印帮助信息 123456789 123456789jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。
jmap用来查看堆内存使用状况,一般结合jhat使用。jmap语法格式如下:
如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。
jmap [option] pid jmap [option] executable core jmap [option] [server-id@]remote-hostname-or-ip # 参数说明 executable 产生core dump的java可执行程序 core 将被打印信息的core dump文件 remote-hostname-or-ip 远程debug服务的主机名或ip server-id 唯一id,假如一台主机上多个远程debug服务 pid 需要被打印配相信息的java进程id,可以用jps查问 # 基本参数 -dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件 -finalizerinfo 打印正等候回收的对象的信息 -heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况 -histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量 -permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来 -F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效 -h | -help 打印辅助信息 -J 传递参数给jmap启动的jvm 1234567891011121314151617181920 1234567891011121314151617181920Jhat用于对JAVA heap进行离线分析的工具,它可以对不同虚拟机中导出的heap信息文件进行分析
# jmap -dump:format=b,file=dumpFileName pid jmap -dump:format=b,file=/tmp/dump.dat 21711 jhat -port 9998 /tmp/dump.dat # 注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存 # 在浏览器中输入主机地址:9998查看 1234567 1234567另外,可以使用Eclipse插件MAT(Memory Analyzer Tool)对dump文件进行分析。
Jstat用于监控基于HotSpot的JVM,对其堆的使用情况进行实时的命令行的统计,使用jstat我们可以对指定的JVM做如下监控:
类的加载及卸载情况查看新生代、老生代及持久代的容量及使用情况查看新生代、老生代及持久代的垃圾收集情况,包括垃圾回收的次数及垃圾回收所占用的时间查看新生代中Eden区及Survior区中容量及分配情况等语法:
jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ] generalOption - 单个的常用的命令行选项,如-help, -options, 或 -version。 outputOptions -一个或多个输出选项,由单个的statOption选项组成,可以和-t, -h, and -J等选项配合使用。 statOption 根据jstat统计的维度不同,可以使用如下表中的选项进行不同维度的统计,不同的操作系统支持的选项可能会不一样,可以通过-options选项,查看不同操作系统所支持选项 -h n 用于指定每隔几行就输出列头,如果不指定,默认是只在第一行出现列头。 -J javaOption 用于将给定的javaOption传给java应用程序加载器,例如,“-J-Xms48m”将把启动内存设置为48M -t n 用于在输出内容的第一列显示时间戳,这个时间戳代表的时JVM开始启动到现在的时间 vmid VM的进程号,即当前运行的java进程号 interval 间隔时间,单位可以是秒或者毫秒,通过指定s或ms确定,默认单位为毫秒 count 打印次数,如果缺省则打印无数次 12345678910111213 12345678910111213统计维度与输出
class 用于查看类加载情况的统计 列名 说明 Loaded 加载了的类的数量 Bytes 加载了的类的大小,单为Kb Unloaded 卸载了的类的数量 Bytes 卸载了的类的大小,单为Kb Time 花在类的加载及卸载的时间2. compiler 用于查看HotSpot中即时编译器编译情况的统计
列名 说明 Compiled 编译任务执行的次数 Failed 编译任务执行失败的次数 Invalid 编译任务非法执行的次数 Time 执行编译花费的时间 FailedType 最后一次编译失败的编译类型 FailedMethod 最后一次编译失败的类名及方法名3. gc 用于查看JVM中堆的垃圾收集情况的统计
列名 说明 S0C 新生代中Survivor space中S0当前容量的大小(KB) S1C 新生代中Survivor space中S1当前容量的大小(KB) S0U 新生代中Survivor space中S0容量使用的大小(KB) S1U 新生代中Survivor space中S1容量使用的大小(KB) EC Eden space当前容量的大小(KB) EU Eden space容量使用的大小(KB) OC Old space当前容量的大小(KB) OU Old space使用容量的大小(KB) PC Permanent space当前容量的大小(KB) PU Permanent space使用容量的大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 YGCT 从应用程序启动到采样时 Young GC 所用的时间(秒) FGC 从应用程序启动到采样时发生 Full GC 的次数 FGCT 从应用程序启动到采样时 Full GC 所用的时间(秒) GCT T从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC4. gccapacity 用于查看新生代、老生代及持久代的存储容量情况
列名 说明 NGCMN 新生代的最小容量大小(KB) NGCMX 新生代的最大容量大小(KB) NGC 当前新生代的容量大小(KB) S0C 当前新生代中survivor space 0的容量大小(KB) S1C 当前新生代中survivor space 1的容量大小(KB) EC Eden space当前容量的大小(KB) OGCMN 老生代的最小容量大小(KB) OGCMX 老生代的最大容量大小(KB) OGC 当前老生代的容量大小(KB) OC 当前老生代的空间容量大小(KB) PGCMN 持久代的最小容量大小(KB) PGCMX 持久代的最大容量大小(KB) PGC 当前持久代的容量大小(KB) PC 当前持久代的空间容量大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 FGC 从应用程序启动到采样时发生 Full GC 的次数5. gccause 用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因。
列名 说明 LGCC 最后一次垃圾收集的原因,可能为“unknown GCCause”、“System.gc()”等 GCC 当前垃圾收集的原因6. gcnew 用于查看新生代垃圾收集的情况
列名 说明 S0C 当前新生代中survivor space 0的容量大小(KB) S1C 当前新生代中survivor space 1的容量大小(KB) S0U S0已经使用的大小(KB) S1U S1已经使用的大小(KB) TT Tenuring threshold,要了解这个参数,我们需要了解一点Java内存对象的结构,在Sun JVM中,(除了数组之外的)对象都有两个机器字(words)的头部。第一个字中包含这个对象的标示哈希码以及其他一些类似锁状态和等标识信息,第二个字中包含一个指向对象的类的引用,其中第二个字节就会被垃圾收集算法使用到。 在新生代中做垃圾收集的时候,每次复制一个对象后,将增加这个对象的收集计数,当一个对象在新生代中被复制了一定次数后,该算法即判定该对象是长周期的对象,把他移动到老生代,这个阈值叫着tenuring threshold。这个阈值用于表示某个/些在执行批定次数youngGC后还活着的对象,即使此时新生的的Survior没有满,也同样被认为是长周期对象,将会被移到老生代中。 MTT Maximum tenuring threshold,用于表示TT的最大值。 DSS Desired survivor size (KB).可以参与这里:http://blog.csdn.net/yangjun2/article/details/6542357 EC Eden space当前容量的大小(KB) EU Eden space已经使用的大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 YGCT 从应用程序启动到采样时 Young GC 所用的时间(单位秒)7. gcnewcapacity 用于查看新生代的存储容量情况
列名 说明 NGCMN 新生代的最小容量大小(KB) NGCMX 新生代的最大容量大小(KB) NGC 当前新生代的容量大小(KB) S0CMX 新生代中SO的最大容量大小(KB) S0C 当前新生代中SO的容量大小(KB) S1CMX 新生代中S1的最大容量大小(KB) S1C 当前新生代中S1的容量大小(KB) ECMX 新生代中Eden的最大容量大小(KB) EC 当前新生代中Eden的容量大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 FGC 从应用程序启动到采样时发生 Full GC 的次数8. gcold 用于查看老生代及持久代发生GC的情况
列名 说明 PC 当前持久代容量的大小(KB) PU 持久代使用容量的大小(KB) OC 当前老年代容量的大小(KB) OU 老年代使用容量的大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 FGC 从应用程序启动到采样时发生 Full GC 的次数 FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC9. gcoldcapacity 用于查看老生代的容量
列名 说明 OGCMN 老生代的最小容量大小(KB) OGCMX 老生代的最大容量大小(KB) OGC 当前老生代的容量大小(KB) OC 当前新生代的空间容量大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 FGC 从应用程序启动到采样时发生 Full GC 的次数 FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC10. gcpermcapacity 用于查看持久代的容量
列名 说明 PGCMN 持久代的最小容量大小(KB) PGCMX 持久代的最大容量大小(KB) PGC 当前持久代的容量大小(KB) PC 当前持久代的空间容量大小(KB) YGC 从应用程序启动到采样时发生 Young GC 的次数 FGC Full GC次数 FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC11. gcutil 用于查看新生代、老生代及持代垃圾收集的情况
列名 说明 S0 Heap上的 Survivor space 0 区已使用空间的百分比 S1 Heap上的 Survivor space 1 区已使用空间的百分比 E Heap上的 Eden space 区已使用空间的百分比 O Heap上的 Old space 区已使用空间的百分比 P Perm space 区已使用空间的百分比 YGC 从应用程序启动到采样时发生 Young GC 的次数 YGCT 从应用程序启动到采样时 Young GC 所用的时间(单位秒) FGC 从应用程序启动到采样时发生 Full GC 的次数 FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒) GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC12. printcompilation HotSpot编译方法的统计
列名 说明 Compiled 编译任务执行的次数 Size 方法的字节码所占的字节数 Type 编译类型 Method 指定确定被编译方法的类名及方法名,类名中使名“/”而不是“.”做为命名分隔符,方法名是被指定的类中的方法,这两个字段的格式是由HotSpot中的“-XX:+PrintComplation”选项确定的。示例
jstat -gc 1618 250 4 1 1jvisualvm同jconsole都是一个基于图形化界面的、可以查看本地及远程的JAVA GUI监控工具,Jvisualvm同jconsole的使用方式一样,直接在命令行打入Jvisualvm即可启动,不过Jvisualvm相比,界面更美观一些,数据更实时。
一个java GUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。用java写的GUI程序,用来监控VM,并可监控远程的VM,非常易用,而且功能非常强。命令行里打 jconsole,选则进程就可以了。
需要注意的就是在运行jconsole之前,必须要先设置环境变量DISPLAY,否则会报错误,Linux下设置环境变量如下: export DISPLAY=:0.0
JProfiler是一个需要商业授权的全功能的Java剖析工具(profiler),专用于分析J2SE和J2EE应用程序。
它把CPU、执行绪和内存的剖析组合在一个强大的应用中。JProfiler可提供许多IDE整合和应用服务器整合用途。JProfiler直觉式的GUI让你可以找到效能瓶颈、抓出内存漏失(memory leaks)、并解决执行绪的问题。它让你得以对heap walker作资源回收器的root analysis,可以轻易找出内存漏失;heap快照(snapshot)模式让未被参照(reference)的对象、稍微被参照的对象、或在终结(finalization)队列的对象都会被移除;整合精灵以便剖析浏览器的Java外挂功能。
Java线程分析工具,专业的线程分析工具兼容sun/oracle JDK dump线程堆,图形化显示线程概括信息,非常容易的定位问题。 jca是一个类工具 启动方法:
java -jar jca433.jar 1 1jinfo可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。用法是jinfo -opt pid 如:查看2788的MaxPerm大小可以用 jinfo -flag MaxPermSize 2788。
用来对core文件和正在运行的Java进程进行实时地调试,里面包含了丰富的命令帮助您进行调试。
jstatd是一个基于RMI(Remove Method Invocation)的服务程序,它用于监控基于HotSpot的JVM中资源的创建及销毁,并且提供了一个远程接口允许远程的监控工具连接到本地的JVM执行命令。
jstatd是基于RMI的,所以在运行jstatd的服务器上必须存在RMI注册中心,如果没有通过选项”-p port”指定要连接的端口,jstatd会尝试连接RMI注册中心的默认端口。后面会谈到如何连接到一个默认的RMI内部注册中心,如何禁止默认的RMI内部注册中心的创建,以及如何启动一个外部注册中心。
参数选项
-nr 如果RMI注册中心没有找到,不会创建一个内部的RMI注册中心。 -p port RMI注册中心的端口号,默认为1099。 -n rminame 默认为JStatRemoteHost;如果同一台主机上同时运行了多个jstatd服务,rminame可以用于唯一确定一个jstatd服务;这里需要注意一下,如果开启了这个选项,那么监控客户端远程连接时,必须同时指定hostid及vmid,才可以唯一确定要连接的服务,这个可以参看jps章节中列出远程服务器上Java进程的示例。 -J 用于传递jvm选项到由javac调用的java加载器中,例如,“-J-Xms48m”将把启动内存设置为48M,使用-J选项可以非常方便的向基于Java的开发的底层虚拟机应用程序传递参数。 1234 1234安全性
jstatd服务只能监视具有适当的本地访问权限的JVM,因此jstatd进程与被监控的JVM必须运行在相同的用户权限中。但是有一些特殊的用户权限,如基于UNIX(TM)为系统的root用户,它有权限访问系统中所有JVM的资源,如果jstatd进程运行在这种权限中,那么它可以监视系统中的所有JVM,但是这也带来了额外的安全问题。
示例
# 使用内部RMI注册中心(默认端口是1099),启动jstatd jstatd -J-Djava.security.policy=jstatd.all.policy # 使用外部的RMI注册中心,启动jstatd rmiregistry&jstatd -J-Djava.security.policy=all.policy # 外部的RMI注册中心来启动jstatd,此注册中心的端口为2020 rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 # 外部的RMI注册中心来启动jstatd,此注册中心的端口为2020,并且绑定到RMI注册中心的名为AlternateJstatdServerName rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 -n AlternateJstatdServerName # 禁止内部RMI注册中心的创建 jstatd -J-Djava.security.policy=all.policy -nr # 开启RMI日记记录,jstatd运行在开启了日志记录功能的RMI注册中 jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.logCalls=true 1234567891011121314151617 1234567891011121314151617网页数据分析工具,对客户端到服务器端的请求,响应数据有效的监控分析。
catalina.sh(只运行一个Tomcat)
# 8G内存 JAVA_OPTS=" -Dfile.encoding=UTF-8 -server -Djava.awt.headless=true -Xms6144m -Xmx6144m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC" # 16G内存(垃圾回收略) JAVA_OPTS=" -Dfile.encoding=UTF-8 -server -Xms13312m -Xmx13312m -XX:NewSize=3072m -XX:MaxNewSize=4096m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC" # 32G内存(垃圾回收略) JAVA_OPTS=" -Dfile.encoding=UTF-8 -server -Xms29696m -Xmx29696m -XX:NewSize=6144m -XX:MaxNewSize=9216m -XX:PermSize=1024m -XX:MaxPermSize=1024m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC" 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950建议Hadoop进程的GC参数加上如下选项,很多商业版都默认加上了,这对JDK性能提升有很大帮助:
-XX:CMSInitiatingOccupancyFraction=70 -XX:+HeapDumpOnOutOfMemoryError -XX:+UseConcMarkSweepGC -XX:-CMSConcurrentMTEnabled -XX:+CMSIncrementalMode -Djava.net.preferIPv4Stack=true 123456 123456JDK8中JVM堆内存划分
JDK8引进的JVM参数变化记录
JVM 不稳定参数
java 8 JVM性能优化
Java性能优化攻略详解
Jvm垃圾回收器详细
JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
jps命令(Java Virtual Machine Process Status Tool)
Tomcat 8 安装和配置、优化