アプリケーションが遅く、JVMがシングルCPUセットアップとJava 12以降で頻繁にハングする


24

クライアントアプリケーションがあります(10年以上の開発)。最近、そのJDKがOpenJDK 11からOpenJDK 14にアップグレードされました。シングルCPU(ハイパースレッディングが無効)のWindows 10セットアップ(および使用可能なCPUが1つだけのVirtualBoxマシン内)では、Java 11に比べてアプリケーションの起動が非常に遅くなります。さらに、ほとんどの場合100%のCPUを使用します。プロセッサアフィニティを1つのCPUのみに設定することで問題を再現することもできます(c:\windows\system32\cmd.exe /C start /affinity 1 ...)。

私のVirtualBoxマシンでアプリケーションを開始し、最小限の手動操作でクエリを実行することによる測定:

  • OpenJDK 11.0.2:36秒
  • OpenJDK 13.0.2:〜1.5分
  • OpenJDK 13.0.2 with -XX:-UseBiasedLocking:46秒
  • OpenJDK 13.0.2 with -XX:-ThreadLocalHandshakes:40秒
  • OpenJDK 14:5〜6分
  • OpenJDK 14 with -XX:-UseBiasedLocking:3-3,5分
  • OpenJDK 15 EAビルド20:〜4,5分

使用されているJDK(および上記のオプション)のみが変更されています。(-XX:-ThreadLocalHandshakesJava 14では使用できません。)

JDK 14で何ができるかをログに記録してみました-Xlog:all=debug:file=app.txt:uptime,tid,level,tags:filecount=50

OpenJDK 11.0.2では、毎秒のログ行を数えるのは非常にスムーズに見えます。

$ cat jdk11-log/app* | grep "^\[" | cut -d. -f 1 | cut -d[ -f 2 | sort | uniq -c | sort -k 2 -n
  30710 0
  44012 1
  55461 2
  55974 3
  27182 4
  41292 5
  43796 6
  51889 7
  54170 8
  58850 9
  51422 10
  44378 11
  41405 12
  53589 13
  41696 14
  29526 15
   2350 16
  50228 17
  62623 18
  42684 19
  45045 20

一方、OpenJDK 14には興味深い休止期間があるようです。

$ cat jdk14-log/app* | grep "^\[" | cut -d. -f 1 | cut -d[ -f 2 | sort | uniq -c | sort -k 2 -n
   7726 0
   1715 5
  10744 6
   4341 11
  42792 12
  45979 13
  38783 14
  17253 21
  34747 22
   1025 28
   2079 33
   2398 39
   3016 44

では、1〜4秒、7〜10秒、14〜20秒の間に何が起こっているのでしょうか。

...
[0.350s][7248][debug][class,resolve        ] jdk.internal.ref.CleanerFactory$1 java.lang.Thread CleanerFactory.java:45
[0.350s][7248][debug][class,resolve        ] jdk.internal.ref.CleanerImpl java.lang.Thread CleanerImpl.java:117
[0.350s][7248][info ][biasedlocking        ] Aligned thread 0x000000001727e010 to 0x000000001727e800
[0.350s][7248][info ][os,thread            ] Thread started (tid: 2944, attributes: stacksize: default, flags: CREATE_SUSPENDED STACK_SIZE_PARAM_IS)
[0.350s][6884][info ][os,thread            ] Thread is alive (tid: 6884).
[0.350s][6884][debug][os,thread            ] Thread 6884 stack dimensions: 0x00000000175b0000-0x00000000176b0000 (1024k).
[0.350s][6884][debug][os,thread            ] Thread 6884 stack guard pages activated: 0x00000000175b0000-0x00000000175b4000.
[0.350s][7248][debug][thread,smr           ] tid=7248: Threads::add: new ThreadsList=0x0000000017254500
[0.350s][7248][debug][thread,smr           ] tid=7248: ThreadsSMRSupport::free_list: threads=0x0000000017253d50 is freed.
[0.350s][2944][info ][os,thread            ] Thread is alive (tid: 2944).
[0.350s][2944][debug][os,thread            ] Thread 2944 stack dimensions: 0x00000000177b0000-0x00000000178b0000 (1024k).
[0.350s][2944][debug][os,thread            ] Thread 2944 stack guard pages activated: 0x00000000177b0000-0x00000000177b4000.
[0.351s][2944][debug][class,resolve        ] java.lang.Thread java.lang.Runnable Thread.java:832
[0.351s][2944][debug][class,resolve        ] jdk.internal.ref.CleanerImpl jdk.internal.misc.InnocuousThread CleanerImpl.java:135
[0.351s][2944][debug][class,resolve        ] jdk.internal.ref.CleanerImpl jdk.internal.ref.PhantomCleanable CleanerImpl.java:138
[0.351s][2944][info ][biasedlocking,handshake] JavaThread 0x000000001727e800 handshaking JavaThread 0x000000000286d800 to revoke object 0x00000000c0087f78
[0.351s][2944][debug][vmthread               ] Adding VM operation: HandshakeOneThread
[0.351s][6708][debug][vmthread               ] Evaluating non-safepoint VM operation: HandshakeOneThread
[0.351s][6708][debug][vmoperation            ] begin VM_Operation (0x00000000178af250): HandshakeOneThread, mode: no safepoint, requested by thread 0x000000001727e800

# no log until 5.723s

[5.723s][7248][info ][biasedlocking          ]   Revoked bias of currently-unlocked object
[5.723s][7248][debug][handshake,task         ] Operation: RevokeOneBias for thread 0x000000000286d800, is_vm_thread: false, completed in 94800 ns
[5.723s][7248][debug][class,resolve          ] java.util.zip.ZipFile$CleanableResource java.lang.ref.Cleaner ZipFile.java:715
[5.723s][7248][debug][class,resolve          ] java.lang.ref.Cleaner jdk.internal.ref.CleanerImpl$PhantomCleanableRef Cleaner.java:220
[5.723s][7248][debug][class,resolve          ] java.util.zip.ZipFile$CleanableResource java.util.WeakHashMap ZipFile.java:716
...

少し後の2番目の一時停止:

...
[6.246s][7248][info ][class,load              ] java.awt.Graphics source: jrt:/java.desktop
[6.246s][7248][debug][class,load              ]  klass: 0x0000000100081a00 super: 0x0000000100001080 loader: [loader data: 0x0000000002882bd0 of 'bootstrap'] bytes: 5625 checksum: 0025818f
[6.246s][7248][debug][class,resolve           ] java.awt.Graphics java.lang.Object (super)
[6.246s][7248][info ][class,loader,constraints] updating constraint for name java/awt/Graphics, loader 'bootstrap', by setting class object
[6.246s][7248][debug][jit,compilation         ]   19       4       java.lang.Object::<init> (1 bytes)   made not entrant
[6.246s][7248][debug][vmthread                ] Adding VM operation: HandshakeAllThreads
[6.246s][6708][debug][vmthread                ] Evaluating non-safepoint VM operation: HandshakeAllThreads
[6.246s][6708][debug][vmoperation             ] begin VM_Operation (0x000000000203ddf8): HandshakeAllThreads, mode: no safepoint, requested by thread 0x000000000286d800
[6.246s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026b0800, is_vm_thread: true, completed in 1400 ns
[6.246s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026bb800, is_vm_thread: true, completed in 700 ns
[6.246s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026ef800, is_vm_thread: true, completed in 100 ns
[6.246s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026f0800, is_vm_thread: true, completed in 100 ns
[6.246s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026f1800, is_vm_thread: true, completed in 100 ns
[6.246s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026f4800, is_vm_thread: true, completed in 100 ns
[6.247s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x0000000002768800, is_vm_thread: true, completed in 100 ns
[6.247s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x000000000276e000, is_vm_thread: true, completed in 100 ns
[6.247s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x0000000017268800, is_vm_thread: true, completed in 100 ns
[6.247s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x000000001727e800, is_vm_thread: true, completed in 800 ns

# no log until 11.783s

[11.783s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x000000000286d800, is_vm_thread: true, completed in 6300 ns
[11.783s][6708][info ][handshake               ] Handshake "Deoptimize", Targeted threads: 11, Executed by targeted threads: 0, Total completion time: 5536442500 ns
[11.783s][6708][debug][vmoperation             ] end VM_Operation (0x000000000203ddf8): HandshakeAllThreads, mode: no safepoint, requested by thread 0x000000000286d800
[11.783s][7248][debug][protectiondomain        ] Checking package access
[11.783s][7248][debug][protectiondomain        ] class loader: a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x00000000c0058628} protection domain: a 'java/security/ProtectionDomain'{0x00000000c058b948} loading: 'java/awt/Graphics'
[11.783s][7248][debug][protectiondomain        ] granted
[11.783s][7248][debug][class,resolve           ] sun.launcher.LauncherHelper java.awt.Graphics LauncherHelper.java:816 (reflection)
[11.783s][7248][debug][class,resolve           ] jdk.internal.reflect.Reflection [Ljava.lang.reflect.Method; Reflection.java:300
[11.783s][7248][debug][class,preorder          ] java.lang.PublicMethods$MethodList source: C:\Users\example\AppData\Local\example\stable\jdk\lib\modules
...

次に、3番目のもの:

...
[14.578s][7248][debug][class,preorder          ] java.lang.InheritableThreadLocal source: C:\Users\example\AppData\Local\example\stable\jdk\lib\modules
[14.578s][7248][info ][class,load              ] java.lang.InheritableThreadLocal source: jrt:/java.base
[14.578s][7248][debug][class,load              ]  klass: 0x0000000100124740 super: 0x0000000100021a18 loader: [loader data: 0x0000000002882bd0 of 'bootstrap'] bytes: 1338 checksum: 8013ed55
[14.578s][7248][debug][class,resolve           ] java.lang.InheritableThreadLocal java.lang.ThreadLocal (super)
[14.578s][7248][debug][jit,compilation         ]  699       3       java.lang.ThreadLocal::get (38 bytes)   made not entrant
[14.578s][7248][debug][vmthread                ] Adding VM operation: HandshakeAllThreads
[14.578s][6708][debug][vmthread                ] Evaluating non-safepoint VM operation: HandshakeAllThreads
[14.578s][6708][debug][vmoperation             ] begin VM_Operation (0x000000000203d228): HandshakeAllThreads, mode: no safepoint, requested by thread 0x000000000286d800
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026b0800, is_vm_thread: true, completed in 1600 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026bb800, is_vm_thread: true, completed in 900 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026ef800, is_vm_thread: true, completed in 100 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026f0800, is_vm_thread: true, completed in 100 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026f1800, is_vm_thread: true, completed in 100 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x00000000026f4800, is_vm_thread: true, completed in 0 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x0000000002768800, is_vm_thread: true, completed in 0 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x000000000276e000, is_vm_thread: true, completed in 0 ns
[14.578s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x0000000017268800, is_vm_thread: true, completed in 0 ns
[14.579s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x000000001727e800, is_vm_thread: true, completed in 900 ns

# no log until 21.455s

[21.455s][6708][debug][handshake,task          ] Operation: Deoptimize for thread 0x000000000286d800, is_vm_thread: true, completed in 12100 ns
[21.455s][6708][info ][handshake               ] Handshake "Deoptimize", Targeted threads: 11, Executed by targeted threads: 0, Total completion time: 6876829000 ns
[21.455s][6708][debug][vmoperation             ] end VM_Operation (0x000000000203d228): HandshakeAllThreads, mode: no safepoint, requested by thread 0x000000000286d800
[21.455s][7248][debug][class,resolve           ] sun.security.jca.Providers java.lang.InheritableThreadLocal Providers.java:39
[21.455s][7248][info ][class,init              ] 1251 Initializing 'java/lang/InheritableThreadLocal'(no method) (0x0000000100124740)
[21.455s][7248][debug][class,resolve           ] java.lang.InheritableThreadLocal java.lang.ThreadLocal InheritableThreadLocal.java:57
[21.456s][7248][debug][class,preorder          ] sun.security.jca.ProviderList source: C:\Users\example\AppData\Local\example\stable\jdk\lib\modules
[21.456s][7248][info ][class,load              ] sun.security.jca.ProviderList source: jrt:/java.base
[21.456s][7248][debug][class,load              ]  klass: 0x00000001001249a8 super: 0x0000000100001080 loader: [loader data: 0x0000000002882bd0 of 'bootstrap'] bytes: 11522 checksum: bdc239d2
[21.456s][7248][debug][class,resolve           ] sun.security.jca.ProviderList java.lang.Object (super)
...

次の2行は興味深いようです。

[11.783s][6708][info ][handshake               ] Handshake "Deoptimize", Targeted threads: 11, Executed by targeted threads: 0, Total completion time: 5536442500 ns
[21.455s][6708][info ][handshake               ] Handshake "Deoptimize", Targeted threads: 11, Executed by targeted threads: 0, Total completion time: 6876829000 ns

これらのハンドシェイクに5.5秒と6.8秒かかったのは正常ですか?

このコマンドで実行されているupdate4jデモアプリ(これはアプリケーションとはまったく関係ありません)でも同じ速度低下(および同様のログ)が発生しました。

Z:\swing>\jdk-14\bin\java -Xlog:all=debug:file=app.txt:uptime,tid,level,tags:filecount=50 \
    -jar update4j-1.4.5.jar --remote http://docs.update4j.org/demo/setup.xml

シングルCPUのWindows 10セットアップでアプリをより高速にするために何を探す必要がありますか?アプリケーションで何かを変更したり、JVM引数を追加したりして、これを修正できますか?

これはJDKのバグですか、報告する必要がありますか?

2020-04-25の更新:

私が見る限り、ログファイルにはGCログも含まれています。これらは最初のGCログです。

$ cat app.txt.00 | grep "\[gc"
[0.016s][7248][debug][gc,heap          ] Minimum heap 8388608  Initial heap 60817408  Maximum heap 1073741824
[0.017s][7248][info ][gc,heap,coops    ] Heap address: 0x00000000c0000000, size: 1024 MB, Compressed Oops mode: 32-bit
[0.018s][7248][info ][gc               ] Using Serial
[22.863s][6708][info ][gc,start                ] GC(0) Pause Young (Allocation Failure)
[22.863s][6708][debug][gc,heap                 ] GC(0) Heap before GC invocations=0 (full 0): def new generation   total 17856K, used 15936K [0x00000000c0000000, 0x00000000c1350000, 0x00000000d5550000)
...

残念ながら、3回目の休止後に開始されるため、関連性がないようです。

2020-04-26の更新:

OpenJDK 14では、アプリケーションは私の(シングルCPU)VirtualBoxマシン(i7-6600U CPUで実行)で100%CPUを使用します。仮想マシンには3.5 GBのRAMがあります。タスクマネージャによると、40%以上は無料で、ディスクアクティビティは0%です(これはスワッピングがないことを意味していると思います)。仮想マシンに別のCPUを追加すると(そして物理マシンのハイパースレッディングを有効にすると)、アプリケーションは再び十分に高速になります。マルチコア/ハイパースレッディングCPUでJVMを高速化するために(まれな)シングルCPUマシンでパフォーマンスを失うことは、JDK開発中に意図的なトレードオフでしたか?


3
-Xlog:all=debugGCログを有効に?それは私の一時停止の最初の推測です。
キチク

プロファイラーで実行して結果を比較しましたか?それは自然なことだと思います。
アクセル

1
また、Windowsシステムメッセージを確認し、jdk 14の別のビルドを試してください。他のすべてが失敗した場合は、問題としてエスカレーションしますか?
Khanna111

1
@ Yan.F:OpenJDK 11は永久にはサポートされません。新しいリリースとバグを準備する時が来ました。さらに、それはJDKバグのようです-修正されているかどうかはわかりませんが、他の人を助けることもできます。とにかく、私にとってそれはたいてい好奇心です。一方で、アプリの最小システム要件としてお客様に何を伝えたいのかを説明したいと思います。
palacsint

1
@ Khanna111:はい、答えとして書きました。
palacsint

回答:


6

私の経験から、JDKのパフォーマンスの問題は、主に次のいずれかに関連しています。

  • JITコンパイル
  • VM構成(ヒープサイズ)
  • GCアルゴリズム
  • 正常に動作している既知のアプリケーションを破壊するJVM / JDKの変更
  • (ああ、私はクラスの読み込みについて言及するのを忘れていました...)

OpenJDK11以降のデフォルトのJVM設定のみを使用する場合は、GC、ヒープサイズなど、より目立つオプションのいくつかを固定値に設定する必要があります。

たぶん、いくつかのグラフィカル分析ツールが問題の追跡に役立つ可能性があります。Retrace、AppDynamics、FlightRecorderなどのように。これらは、ログファイルが提供できるよりも、特定の時間におけるヒープ、GCサイクル、RAM、スレッド、CPU負荷などの全体的な状態の概要を示します。

(OpenJDK11で)実行してから1秒以内に、アプリケーションが約30710行をログに書き込むことを正しく理解していますか?最初の1秒間にOpenJDK14で約7k行を「のみ」書き込むのはなぜですか?これは、別のJVMで起動したばかりのアプリケーションにとって、大きな違いのように思われます...たとえば、ログに大量の例外スタックトレースがダンプされていないのは確かですか?
他の数値は時々さらに大きくなるので、おそらくスローダウンは例外ロギングに関連していますか?または、RAMが少なくなった場合は交換することもできますか?
実際、私が考えているのは、アプリケーションがログに何も書き込まない場合、これは問題なくスムーズに実行されていることの兆候です(今回は完全にフリーズされない限り)。12-22秒(ここではOpenJDK14の場合)から何が起こっているのでしょう?ログに記録された行が屋根を通過します... なぜですか?
そして、その後のログは理由何です... 1-2k程度のラインのすべての時間低い値に下がることは?(まあ、それは多分それが秒22でキックインしているgcであり、いくつかのことを解決する表ラサをします...?)

もう1つは、「シングルCPU」マシンに関する記述かもしれません。これは「シングルコア」も意味しますか(Idk、おそらくソフトウェアはレガシーハードウェアなどに合わせて調整されています)。そして、「シングルCPU」のVMがそれらのマシンで実行されていますか?しかし、私はこれらの仮定について間違っていると思います。ほとんどすべてのCPUが今日マルチコアであるためです...しかし、マルチスレッドの問題(デッドロック)の問題について調査するかもしれません。


2
投稿で署名やキャッチフレーズを使用しないでください。繰り返し行われる「GLとHF」はノイズとみなされ、投稿のコンテンツからの注意をそらします。詳細については、meta.stackexchange.com / help / behaviorを参照してください。
貧弱

1
「(OpenJDK11で)実行してから1秒以内に、アプリケーションがログに約30710行を書き込むことを正しく理解していますか?」- はい、あなたが正しい。
palacsint

1
「たとえば、ログに大量の例外スタックトレースがダンプされていないことを確認しますか?」-ログはクリーンで、そこに奇妙なものは何も見つかりませんでした。アプリケーションは正常に動作します(非常にゆっくり実行されることを除いて)。
palacsint

1
GCが22秒でキックしていて、その後アプリは遅いままです。質問も更新しました。update4jデモアプリにも同じ問題があることに注意してください。答えてくれてありがとう!
palacsint

1
1秒あたり30k以上のログ行は非常に巨大です...同意しませんか?このような短時間で大量のログ行を受け入れるには、何をログに記録すると便利なのでしょうか。ログを完全にオフにして、このモードでアプリケーションのプロファイルを作成しましたか?(私は好奇心が強いですが、おそらくupdate4jの動作を示唆しているため、ロギングは実際には影響しません)
アンタレス

5

「ほとんどの場合」100%CPUを使用しており、Java 14では10倍(!)長くかかります。これは、Java 14でCPUの90%を浪費していることを意味します。

ヒープ領域不足すると、GCで長い時間を費やすのでそれが可能ですが、それを除外しているようです。

バイアスロックオプションを微調整していることに気付きました。それはおそらくあなたのプログラムが複数のスレッドで多くの並行作業をしていることを教えてくれます。Java 10ではなくJava 14で発生する並行性のバグがプログラムにある可能性があります。これは、別のCPUを追加すると2倍以上の速度になる理由も説明できます。

並行性のバグは、多くの場合、運が悪いときにのみ表示され、トリガーは、ハッシュマップ構成の変更など、実際には何でもかまいません。

まず、可能であれば、スリープではなくビジー待機である可能性のあるループを確認します。

次に、プロファイラーをサンプリングモードで実行し(jvisualvmが実行します)、合計時間の%が必要以上に長いメソッドを探します。パフォーマンスが10倍下がっているので、そこにある問題はすべて実際に飛び出すはずです。


バイアスロックは以前は必要でしたが、現在はそれほど多くなく、デフォルトで無効にして後で削除することが提案されています:openjdk.java.net/jeps/374
JohannesB

3

TL; DR:これはOpenJDKの退行です。

それ以外は行いませんでしたが、単純なHello Worldで問題を再現できました。

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}

次の2つのバッチファイルを使用しました。

main-1cpu.batjavaプロセスを1つのCPUのみに制限します。

c:\windows\system32\cmd.exe /C start /affinity 1 \
    \jdk-14\bin\java \
    -Xlog:all=trace:file=app-1cpu.txt:uptime,tid,level,tags:filecount=50 \
    Main

main-full.batjavaプロセスは両方のCPUを使用できます。

c:\windows\system32\cmd.exe /C start /affinity FF \
    \jdk-14\bin\java \
    -Xlog:all=trace:file=app-full.txt:uptime,tid,level,tags:filecount=50 \
    Main

(違いはaffinityログファイルの値と名前です。読みやすくするためにラップしましたが、\おそらくWindowsではラップできません。)

VirtualBoxのWindows 10 x64でのいくつかの測定(2つのCPUを使用):

PS Z:\main> Measure-Command { .\main-1cpu.bat }

...    
TotalSeconds      : 7.0203455
...


PS Z:\main> Measure-Command { .\main-full.bat }

...
TotalSeconds      : 1.5751352
...


PS Z:\main> Measure-Command { .\main-full.bat }

...
TotalSeconds      : 1.5585384
...


PS Z:\main> Measure-Command { .\main-1cpu.bat }

...
TotalSeconds      : 23.6482685
...

生成されたトレースログには、質問で確認できる同様の一時停止が含まれています。

実行Maintracelogsなしでは高速ですが、違いはまだ、シングルCPUと2-CPUのバージョン間で見ることができます:〜4-7秒対〜400ミリ。

私が送信したホットスポット-devの@ OpenJDKのメールリストに、この調査結果をしていることが確認さDEVS これはJDKが良く扱うことができることを何かです想定される修正もスレッドで見つけることができます。うまくいけば、それはOpenJDK 15で修正されるでしょう。


2

これは興味深い問題であり、試行してデータを収集して照合する必要がある多くの順列と組み合わせがあるため、それを絞り込むには不確定な量の労力が必要になります。

しばらくの間、これに対する解決策はないようです。おそらくこれをエスカレーションする必要があるかもしれません。

編集2:「ThreadLocalHandshakes」は非推奨であり、ロックが競合していると想定できるため、「UseBiasedLocking」を使用しないでこのシナリオを高速化することをお勧めします。

ただし、より多くのデータを収集して問題を切り分けようとするいくつかの提案があります。

  1. 複数のコアを割り当てる[あなたはそれを試し、問題は解消したようです。スレッドの実行が他を妨げている問題のようです。下の7を参照)
  2. より多くのヒープを割り当てる(おそらく、v14の要求は以前のjdkの要求よりも多い)
  3. Win 10 VBにより多くのメモリを割り当てます。
  4. OSシステムメッセージを確認します(あなたの場合はWin 10)
  5. 仮想化されていないWin 10で実行します。
  6. jdk 14の別のビルドを試す
  7. いくつかの時間間隔(またはプロファイル)ごとにスレッドダンプを行います。排他的に実行されているスレッドを分析します。おそらく、公平な時分割のための設定があります。おそらく、より優先度の高いスレッドが実行されています。そのスレッドとは何ですか?Linuxでは、プロセスに関連付けられた軽量プロセス(スレッド)とその状態をリアルタイムで統計できます。Win 10で似ているものはありますか?
  8. CPU使用率?100%以下?CPUまたはメモリによって制約されていますか?100%CPU in service threads?どのサービススレッドですか?
  9. GCアルゴを明示的に設定しましたか?

私は、GC、ヒープのサイズ変更、仮想化コンテナーの問題などに関連するバージョン内の問題を個人的に目撃しました。

これに対する簡単な答えはないと思います。特に、この質問はしばらく前から出回っていたためです。しかし、最善を尽くして、これらの分離手順の結果が何であるかをお知らせすることができます。

編集1:更新された質問から、それはGCまたは他のサービススレッドが単一コアを不平等に引き継ぐことに関連しているようです(スレッドローカルハンドシェイク)?


パフォーマンスとメモリ使用量の突然の違いを説明できる可能性がある場合は、クライアントから32ビットシステムのJavaエルゴノミクスからクライアントからサーバークラスvmへの切り替えをトリガーするために使用される余分なCPUコアを追加します。パフォーマンスが😁複雑さ
JohannesB

3
Javaのエルゴノミクス(デフォルト設定)は、1 CPU(例:-XX:+ UseSerialGC)または2 CPU(例:G1GC、LoopStripMiningIter = 1000、... ShortLoop = 100)ではまだ異なりますが、-XX:+で確認した後すべてのパラメータを同じまたは同様のupdate4jを実行するように微調整したPrintFlagsFinalは、cmd.exe / C start / affinity 0x1を使用して2つのCPUではなく1つのCPUで開始するのが非常に遅くなりました(ただし0x3で非常に高速です-したがって、2 CPU(1 + 10バイナリ))。GCのオーバーヘッドを回避するように設計されたEpsilon GCを使用しても、ガベージコレクターのせいにすることはできません。TieredCompilationは有効です
JohannesB

そうですか。Epsilon GCでは、まるで遅いかのようです。この場合、どこにスタックしているのかを評価するためのスレッドステータスとダンプが有効な場合があります。Javaの世界とOSの世界の両方(私が覚えていればLinuxはgcoreでした)
Khanna111

1

遅いディスクへのロギングに注意してください。アプリケーションの速度が低下します。

https://engineering.linkedin.com/blog/2016/02/eliminating-large-jvm-gc-pauses-caused-by-background-io-traffic

しかし、CPUがまだビジーであり、スレッドローカルハンドシェイクのおかげですべてのスレッドが安全なポイントに到達するのを待つ必要がないため、それが問題の原因であるとは思われません:https:// openjdk。 java.net/jeps/312

また、発生している問題には直接関係していませんが、より一般的には、起動時にハードウェアからより多くのパフォーマンスを引き出そうとする場合は、AppCDS(クラスデータ共有)をご覧ください。

https://blog.codefx.org/java/application-class-data-sharing/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.