一部の学生が、いくつかの時間のためのJavaを書くことが、JVMのために非常に心配されていません。一部の学生がこのようなものをパラメータが良いチームを指定している、私は手を展開する時間がない、フォーカスがどのような使用上のそれであると言う、と、JVM、それは非常に神秘的な感じ非常に深い道を鳴らし、またはそれを忘れています。
はい、あなたがより少ないハンズオンよりかもしれ展開が、質問が何をどのように生じたとき、あなたは問題を解決しないと、JVMの理解が十分でない場合は、いくつかの問題は非常に骨の折れる、あるいは解決することは不可能そのトラブルシューティングがあります。
この部分は共通パラメータJVMに関する背景として、8 JDKホットスポットへ。私はあなたには、いくつかの小さなプロジェクト、時間の小さなデモ、一緒にこれらのパラメータ、より深い印象を行う示唆しています。私の経験で、あなただけを使い始めるされているいくつかの知識は、それが難しい理解することがありますが、それは問題で、物事がうまく困難ですしない、知識を消化時間を必要とします。初日はを通じて突然感じ、突然種類啓発の、あなたを、理解していないとしても、月を理解していないが、今の気持ちは常にあります。最後に、彼らは学び、何日前にこれらの知識を学び保つために始めることができるというのが私の心に感謝。
唯一のいくつかの一般的なパラメータを説明し、これらの共通のパラメータに加えて、ホットスポットも問題ないはずですが、それぞれが他の多くのパラメータを提供します。
これらのパラメータを使用する前に、あなたは、Javaメモリモデルのいくつかの理解、メモリモデルを見てする必要があります。
またはマップメモリモデルを理解しやすい、ここに配置する必要があります。
ヒープパラメータ:
-Xms:スタックの初期値、例えば-Xmx2048、2Gの初期ヒープサイズ
-Xmx:最大ヒープ、例えば-Xmx2048M、許容最大ヒープメモリ2G
-Xmn:新世代のサイズ
-XX:SurvivorRatio:エデン面積率は、デフォルト8、すなわち80%であり、例えば-XX:SurvivorRatio = 8
同様に開始するように構成されているように、好ましくは同じ値に値を設定-Xmsと-Xmxは、のように動的に、ヒープ領域の使用量の増加を防止するヒープのサイズを調整するために行われ、性能のいくらかの損失がありますパフォーマンスの損失を回避する値。
スタックパラメータ
-Xss:栈空间大小,栈是线程独占的,所以是一个线程使用栈空间的大小,例如 -Xss256K,如果不设置此参数,默认值是 1M,一般来讲设置成 256K 就足够了。
Metaspace 参数
-XX:MetaspaceSize:Metaspace 空间初始大小,如果不设置的话,默认是20.79M,这个初始大小是触发首次 Metaspace Full GC 的阈值,例如 -XX:MetaspaceSize=256M
-XX:MaxMetaspaceSize:Metaspace 最大值,默认不限制大小,但是线上环境建议设置,例如
-XX:MaxMetaspaceSize=256M
-XX:MinMetaspaceFreeRatio:最小空闲比,当 Metaspace 发生 GC 后,会计算 Metaspace 的空闲比,如果空闲比(空闲空间/当前 Metaspace 大小)小于此值,就会触发 Metaspace 扩容。默认值是 40 ,也就是 40%,例如 -XX:MinMetaspaceFreeRatio=40
-XX:MaxMetaspaceFreeRatio:最大空闲比,当 Metaspace 发生 GC 后,会计算 Metaspace 的空闲比,如果空闲比(空闲空间/当前 Metaspace 大小)大于此值,就会触发 Metaspace 释放空间。默认值是 70 ,也就是 70%,例如 -XX:MaxMetaspaceFreeRatio=70
建议将 MetaspaceSize 和 MaxMetaspaceSize 设置为同样大小,避免频繁扩容。
GC 日志
简单日志
-verbose:gc 或者 -XX:+PrintGC
日志格式:
[GC (Allocation Failure) 7892K->5646K(19456K), 0.0060442 secs]
[GC (Allocation Failure) , 0.0066315 secs]
[Full GC (Allocation Failure) 19302K->13646K(19456K), 0.0032698 secs]
详细日志
#打印详细日志
-XX:+PrintGCDetails
#打印 GC 的时间点
-XX:+PrintGCDateStamps
日志格式:
2019-11-13T14:06:46.099-0800: [GC (Allocation Failure) 2019-11-13T14:06:46.099-0800: [DefNew (promotion failed) : 9180K->9157K(9216K), 0.0084297 secs]2019-11-13T14:06:46.107-0800: [Tenured: 10145K->10145K(10240K), 0.0035768 secs] 13802K->13646K(19456K), [Metaspace: 3895K->3895K(1056768K)], 0.0120887 secs] [Times: user=0.00 sys=0.00, real=0.02 secs]
2019-11-13T14:06:47.243-0800: [Full GC (Allocation Failure) 2019-11-13T14:06:47.244-0800: [Tenured: 10145K->10145K(10240K), 0.0042686 secs] 19304K->19146K(19456K), [Metaspace: 3895K->3895K(1056768K)], 0.0043232 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
以下几个 GC 日志相关的参数打印的内容比较多,生产环境可选择性开启,大多数时候不需要开启。
GC 前后的堆信息
-XX:+PrintHeapAtGC
{Heap before GC invocations=0 (full 0):
def new generation total 9216K, used 7892K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
eden space 8192K, 96% used [0x00000007bec00000, 0x00000007bf3b5200,
xxx....
class space used 445K, capacity 462K, committed 512K, reserved 1048576K
Heap after GC invocations=1 (full 0):
def new generation total 9216K, used 1023K [0x00000007bec00000,
xxx...
Metaspace used 3892K, capacity 4646K, committed 4864K, reserved 1056768K
class space used 445K, capacity 462K, committed 512K, reserved 1048576K
}
GC 导致的 Stop the world 时间
-XX:+PrintGCApplicationStoppedTime
Total time for which application threads were stopped: 0.0070384 seconds, Stopping threads took: 0.0000200 seconds
加载类信息
-verbose:class
[Loaded java.net.URLClassLoader$3$1 from /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/rt.jar]
GC 前后的类加载情况
-XX:+PrintClassHistogramBeforeFullGC
-XX:+PrintClassHistogramAfterFullGC
num #instances #bytes class name
----------------------------------------------
1: 140 19016264 [B
2: 2853 226256 [C
3: 138 169072 [I
4: 761 86240 java.lang.Class
5: 2850 68400 java.lang.String
6: 660 41024 [Ljava.lang.Object;
日志输出到文件
以上参数配置好之后,默认会输出到控制台或者服务指定的统一日志的位置。但是这里还会有服务的一般性信息日志、错误日志等,都混在一起的话会比较乱,所以,一般都会把 jvm 日志单独存放。
#GC 活动日志,根据配置的参数输出内容
-Xloggc:/Users/fengzheng/jvmlog/gc.log
#致命错误日志,只有在 jvm 发生崩溃的时候会输出
-XX:ErrorFile=/Users/fengzheng/jvmlog/hs_err_pid%p.log
堆溢出现场保留
有些错误虽然不会导致 jvm 崩溃,但是对于服务而言也是非常严重的,比如stackOverflow、OutOfMemoryError,发生错误后,留存现场信息对分析错误原因是至关重要的。jvm 提供了保留堆溢出现场的方法,对于 JDK 8 而言,可能是 heap 溢出,也可能是 Metasapce 溢出。
-XX:HeapDumpPath=/Users/fengzheng/jvmlog
-XX:+HeapDumpOnOutOfMemoryError
最后出现异常后,保存的文件格式为 java_pidxxx.hprof,pid 后面是发生溢出的进程 id,之后可以用 VisualVM、JProfiler 等工具打开分析。
设置垃圾回收器类型
随着 JDK 版本的升级,可使用的垃圾收集器类型也越来越多了。JDK 8 可使用的垃圾收集器有 7 种,当然有点只适用于年轻代,有点只使用于老年代,JDK 8 中最新的垃圾收集器是 G1,可以用于年轻代和老年代。到了 JDK 11,还出了 ZGC。
下图是 JDK 8 中可使用的垃圾收集器以及它们配合使用的关系。
Serial、ParNew、Parallel Scavenge 只适用于年轻代,CMS、Serial Old、Parallel Old 只适用于老年代,而 G1 通用于年轻代和老年代。连线表示它们之间可配合使用的关系,其中 CMS 和 Serial Old 连线的意思是说 Serial Old 会作为 CMS 的后预案,当 CMS 发生 Concurrent Mode Failure 时启用。
在 JDK 8 中,如果不指定垃圾收集器,默认使用参数 -XX:+UseParallelGC
,新生代使用 Parallel Scavenge,老年代使用 Serial Old。
-XX:+ UseSerialGC:デフォルト設定はシリアル+シリアル古い、クライアントモードで実行を使用します
-XX:+ UseConcMarkSweepGCを:使用ParNew + CMS +シリアル古い、CMSのガベージコレクタ
-XX:+ UseParallelGC:パラレルシリアル清掃を+旧、JDK 8サーバモードのデフォルト設定
-XX:+ UseParallelOldGC:パラレル清掃を+パラレル古いです
-XX:+ UseG1GC:G1ガベージコレクタを使用して
リモートJMXモニタリングを開きます
私たちが行う方法のリアルタイムJVMの操作を表示する必要がある場合に、ログに加えて、もちろん、あなたが閲覧するためのjstack、jmapは、Jinfoのおよび他のツールとJVMのホストサーバに行くことができますが、それは直感的ではありませんが、この時点で、あなたはJMXリモート機能を開く必要があり、JConsoleを使用します、VisualVMのおよび監視するための他のツール。または、独自の監視プラットフォームを開発
次のように開き、パラメータは次のとおりです。
-Dcom.sun.management.jmxremote
#指定 jvm 所在服务器 ip 或域名
-Djava.rmi.server.hostname=192.168.1.1
#指定端口
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false