应用程序速度慢,频繁的JVM因单CPU设置和Java 12+而挂起


23

我们有一个客户应用程序(经过10多年的发展)。其JDK最近从OpenJDK 11升级到OpenJDK 14。与Java 11相比,在单CPU(禁用超线程)的Windows 10设置(以及仅具有一个可用CPU的VirtualBox机器中)中,应用程序启动速度非常慢。此外,该应用程序大多数时候都使用100%CPU。我们还可以通过将处理器关联性设置为仅一个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与 -XX:-UseBiasedLocking:46秒
  • OpenJDK 13.0.2与 -XX:-ThreadLocalHandshakes:40秒
  • OpenJDK 14:5-6分钟
  • OpenJDK 14与 -XX:-UseBiasedLocking:3-3.5分钟
  • OpenJDK 15 EA Build 20:约4.5分钟

仅更改了使用的JDK(以及上述选项)。(-XX:-ThreadLocalHandshakes在Java 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
...

第二个暂停稍后:

...
[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
...

然后是第三个:

...
[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)
...

以下两行似乎很有趣:

[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)
...

不幸的是,它似乎并不相关,因为它是在第三个暂停之后开始的。

更新2020-04-26:

使用OpenJDK 14,应用程序在我的(单CPU)VirtualBox计算机(在i7-6600U CPU上运行)中使用100%的CPU。虚拟机具有3,5 GB RAM。根据任务管理器,40%+是免费的,磁盘活动是0%(我想这意味着没有交换空间)。向虚拟机添加另一个CPU(并为物理机启用超线程)使应用程序再次足够快。我只是想知道,在JDK开发过程中是否有意在权衡下牺牲(罕见)单CPU机器上的性能,以使多核/超线程CPU上的JVM更快?


3
是否-Xlog:all=debug打开GC日志记录?对于任何暂停,这都是我的第一个猜测。
kichik

您是否尝试使用探查器运行并比较结果?我认为那是很自然的事情。
Axel

1
还检查Windows系统消息,为jdk 14尝试其他构建。如果其他所有方法均失败,请升级为问题?
Khanna111

1
@ Yan.F:永远不会支持OpenJDK 11,是时候准备新版本和bug了。此外,它似乎是一个JDK错误-可能已修复或未修复,但也可能对其他人有所帮助。无论如何,对我来说,这主要是好奇。另一方面,我现在想告诉我们的客户什么是我们的应用程序对系统的最低要求。
palacsint

1
@ Khanna111:是的,我只是将其写为答案。
palacsint

Answers:


6

根据我的经验,JDK的性能问题主要与以下问题之一相关:

  • JIT编译
  • VM配置(堆大小)
  • GC算法
  • JVM / JDK中的更改破坏了运行良好的已知应用程序
  • (哦,我忘了讲加载类了……)

如果仅从OpenJDK11开始使用默认的JVM配置,则可能应该将一些更突出的选项设置为固定值,例如GC,堆大小等。

也许某些图形分析工具可以帮助您跟踪问题。如Retrace,AppDynamics或FlightRecorder等。这些在给定的时间提供了比日志文件所能提供的有关堆的总体状态,gc周期,RAM,线程,CPU负载等的更多概述。

我是否正确理解您的应用程序在运行的第一秒内(在OpenJDK11下)向日志写入了约30710行?为什么在第一秒钟内“仅”在OpenJDK14下写大约7k行?对于刚刚在我不同的JVM上启动的应用程序来说,这似乎是一个巨大的区别。例如,您确定没有大量异常堆栈跟踪转储到日志中吗?
有时其他数字甚至更高,因此,速度下降是否与异常日志记录有关?甚至交换,如果RAM变低?
实际上,我在想,如果应用程序未在日志中写入任何内容,则这是运行顺利且没有问题的迹象(除非此时将其完全冻结)。从12到22秒(在此处为OpenJDK14情况)发生的是令我更加关注的问题……记录的行经过屋顶…… 为什么
然后记录又下降到所有时间的低值(约1-) 2k行...是什么原因?(好吧,也许是gc在第二十二秒踢进来了,而表格rasa可以解决一些问题吗??)

另一件事可能是您对“单CPU”计算机的陈述。这是否还意味着“单核”(Idk,也许您的软件是在旧硬件或其他硬件上定制的)?并且那些计算机上正在运行“单CPU” VM?但是我认为,这些假设是错误的,因为当今几乎所有的CPU都是多核的……但是我可能会研究多线程问题(死锁)。


2
请不要在帖子中使用签名或标语,重复的“ GL和HF”被认为是噪音,并且会干扰您在此处发布的内容。有关更多信息,请参见meta.stackexchange.com/help/behavior
meagar

1
“我是否正确理解您的应用程序在运行的第一秒内(在OpenJDK11下)向日志写入了约30710行?” - 你是对的。
palacsint

1
“您确定没有大量异常堆栈跟踪记录转储到日志中吗?” -日志很干净,我在那儿没有发现任何奇怪的东西,该应用程序正常运行(除了运行非常缓慢之外)。
palacsint

1
GC将在第22秒开始播放,此后应用仍然保持缓慢。我也更新了问题。请注意,update4j演示应用程序也存在相同的问题。谢谢您的回答!
palacsint

1
一秒钟内超过30k的日志行非常庞大...您不同意吗?我真的想知道在这么短的时间内记录这么多的日志行可能有用吗...您是否尝试过完全关闭日志记录并以这种模式配置应用程序?(我很好奇,但是也许日志记录确实没有影响,因为您暗示了update4j行为)
Antares

5

由于它“大部分时间”都使用100%CPU,而使用Java 14的时间要长10倍(!),这意味着您在Java 14中浪费了90%的CPU。

耗尽堆空间可以做到这一点,因为您在GC中花费了大量时间,但是您似乎已经排除了这种情况。

我注意到您正在调整“偏向锁定”选项,并且这有很大的不同。这告诉我,也许您的程序在多个线程中做了很多并发工作。您的程序可能会在Java 14中显示并发错误,而在Java 10中却没有。这也可以解释为什么添加另一个CPU会使它的运行速度提高两倍以上。

并发错误通常仅在您不走运时才会出现,并且触发可能确实是什么,例如对哈希映射组织的更改等。

首先,如果可行,请检查是否有可能正在等待而不是休眠的循环。

然后,以采样方式运行事件探查器(jvisualvm会这样做),并寻找所花费的总时间百分比远远超出其所需时间的方法。由于您的性能下降了10倍,因此那里的所有问题都应该跳出来。


偏置锁定在过去是必需的,但如今已不那么多了,建议默认将其禁用,然后将其删除:openjdk.java.net/jeps/374
JohannesB

2

这是一个有趣的问题,由于需要进行许多排列和组合以及收集和整理数据的工作,因此需要花费大量的精力才能缩小范围。

似乎有一段时间没有对此的解决方法了。也许这可能需要升级。

编辑2:由于“ ThreadLocalHandshakes”已被弃用,我们可以假设锁定存在争议,建议尝试不使用“ UseBiasedLocking”以加快此情况。

但是,有一些建议可以收集更多数据并尝试找出问题所在。

  1. 分配多个核心[我看到您已经尝试过,但问题消失了。似乎是一个线程(不包括其他线程)的执行问题。参见下面的第7条)
  2. 分配更多的堆(也许v14的需求比早期jdks的需求更多)
  3. 分配更多的内存到Win 10 VB。
  4. 检查操作系统系统消息(您的情况下为Win 10)
  5. 在非虚拟的Win 10中运行它。
  6. 尝试其他版本的JDK 14
  7. 每隔几个时间间隔进行一次线程转储。分析什么线程专门运行。也许存在公平分时的环境。也许正在运行更高优先级的线程。该线程是什么,它在做什么?在Linux中,您可以实时统计与进程相关联的轻量级进程(线程)及其状态。Win 10上有类似的东西吗?
  8. CPU使用率?100%以下?是否受CPU或内存限制?服务线程中100%CPU?哪个服务线程?
  9. 您是否明确设置了GC算法?

我亲眼目睹了与GC有关的版本中的问题,堆大小调整,虚拟化容器的问题等等。

我认为对此没有简单的答案,特别是因为这个问题已经存在了一段时间。但是我们可以尽力而为,让我们知道其中一些隔离步骤的结果。

编辑1:从更新的问题来看,它似乎与GC或另一个服务线程非平等地接管了单个核心有关(线程本地握手)?


如果仍然可以添加额外的CPU内核,以触发从32位系统上的Java人体工程学从客户端切换到具有不同GC和分层编译的服务器类vm(如果仍然如此,则可以解释性能和内存使用的突然差异,是的)性能很复杂
JohannesB

3
对于1个CPU(例如-XX:+ UseSerialGC)或2个CPU(例如G1GC,LoopStripMiningIter = 1000,... ShortLoop = 100),Java人机工程学(默认设置)仍然不同,但是在确保使用-XX:+之后我将所有参数调整为相同或相似的运行update4j的PrintFlagsFinal,使用cmd.exe / C start / affinity 0x1仅以一个而不是2个CPU来启动仍然非常缓慢(但是使用0x3则非常快-因此使用2 cpus(1 + 10二进制))。我确认我们不能通过使用旨在避免任何GC开销的Epsilon GC来指责任何垃圾收集器。然而,启用了TieredCompilation
JohannesB

我知道了。使用Epsilon GC时,速度似乎很慢。在这种情况下,线程状态和转储以评估其卡在哪里可能是一种方法。在Java世界和OS世界中(如果我还记得的话,Linux都是gcore)
Khanna111

2

TL; DR:这是OpenJDK回归。

除此以外,我没有其他问题,但可以通过一个简单的hello world重现此问题:

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

我已经使用了这两个批处理文件:

main-1cpu.bat,将java进程限制为仅一个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.bat,该java进程可以同时使用两个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上包装可能不起作用。)

Windows 10 x64 VirtualBox(带有两个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
...

产生的跟踪日志包含类似的停顿,您可以在问题中看到。

Main没有跟踪日志的情况下运行速度更快,但是单CPU版本和两CPU版本之间仍然可以看到差异:〜4-7秒vs.〜400 ms。

我已将调查结果发送到hotspot-dev @ openjdk邮件列表,并且那里的开发人员确认这是JDK可以更好地解决的问题。您也可以在线程中找到假定的修复程序。希望它将在OpenJDK 15中修复。


感谢您的反馈!
Antares

1

记录到慢速磁盘时要小心,这会使您的应用程序变慢:

https://engineering.linkedin.com/blog/2016/02/eliminate-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/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.