简体   繁体   English

Java CPU使用率应该是100%......但事实并非如此

[英]Java CPU usage should be 100%… but it's not

I'm running a Java program on my Core i7 laptop which has 8 cores (4 physical, 4 HT). 我正在我的Core i7笔记本电脑上运行一个Java程序,它有8个核心(4个物理,4个HT)。 The program uses 8 parallel threads and so it should use up all the CPU. 该程序使用8个并行线程,因此它应该耗尽所有CPU。 When running with the '-server' parameter, it is at 100% all the time. 使用'-server'参数运行时,它始终为100%。 Without it, it's around 50%-60% overall (always changing with peaks at 100% and dips at 30%). 如果没有它,它总体上大约在50%-60%之间(总是在100%的峰值和30%的下降时变化)。 Here's what I find weird: when I run the program in debug and wait for a moment where CPU usage is especially low (30%) and then suspend execution to look at what the eight threads are doing, none of them are in a blocking state. 这就是我觉得奇怪的事情:当我在调试中运行程序并等待CPU使用率特别低(30%)然后暂停执行以查看八个线程正在做什么时,它们都没有处于阻塞状态。 Furthermore, there's are almost no synchronization between them. 而且,它们之间几乎没有同步。 Here's what I'm wondering: 这就是我想知道的:

  1. What's the difference between server and client VM that would prevent the CPU to reach 100% in client? 服务器和客户端VM之间有什么区别会阻止CPU在客户端达到100%?
  2. In the absence of synchronization, what could be keeping a thread from using up a core fully? 在没有同步的情况下,什么可以阻止线程完全耗尽核心? (probably linked to 1) (可能与1相关)

Edit: Here's a thought: the code allocates big arrays and leaves them to GC pretty quickly. 编辑:这是一个想法:代码分配大数组并很快将它们留给GC。 Does a thread sleep when calling 'new SomethingBig()' and allocating that memory takes time? 调用'new SomethingBig()'并分配该内存需要时间时线程是否会休眠? If there is a single process in the VM handling allocations for a bunch of threads, I guess that could explain why they seem to pause at random, outside of synchronization blocks... 如果VM处理一组线程的分配中有一个进程,我想这可以解释为什么它们似乎在同步块之外随机暂停......

Edit2: I'm pretty sure it is caused by GC now. 编辑2:我很确定它是由GC引起的。 The CPU reaches 100% again if I give the VM 1500Mb instead of the default 500Mb. 如果我给VM 1500Mb而不是默认的500Mb,则CPU再次达到100%。 I think the slowdown doesn't happen in server mode because it uses more memory by default. 我认为在服务器模式下不会发生减速,因为它默认使用更多内存。

Not related to Java specifically, but the number of threads you have should be more than the number of core you have to make best use of your CPU, this is because there are plenty times when a particular thread can not execute, as well as the more obvious waiting on a condition variable held by another thread, threads can be block for other reasons too like a cache miss could require the thread to wait will data is loaded into the cpus cache, it could have to wait for input from some source that is slower than the cpu, virtually memory paging could cause your thread to wait. 特别是与Java没有关系,但是你拥有的线程数应该超过你必须充分利用CPU的核心数量,这是因为有很多时候特定线程无法执行,以及更明显地等待另一个线程持有的条件变量,线程可能因其他原因而被阻塞,因为缓存未命中可能需要线程等待将数据加载到cpus缓存中,它可能必须等待来自某些源的输入比cpu慢,实际上内存分页可能会导致你的线程等待。 By have more threads than you have core, when one thread is blocked for what ever reason, another can make use the that core that is freed up. 通过拥有比核心更多的线程,当一个线程因任何原因被阻塞时,另一个线程可以使用被释放的核心。 A good initial value is about 1.5 X the number of cores you have. 一个好的初始值大约是你拥有的核心数量的1.5倍。

If you want to monitor what the Java threads are doing, you should not be running the App in the debug mode and suspend it. 如果要监视Java线程正在执行的操作,则不应在调试模式下运行App并暂停它。

Rather, you should collect the thread dumps with kill -3 <pid> in the specific interval where the CPU usage drops. 相反,您应该在CPU使用率下降的特定时间间隔内使用kill -3 <pid> 收集线程转储

Related to your second update, you should enable GC logging with time stamps and correlate the slowdowns/CPU usage drops with the times of Young/Full GC collections. 与第二次更新相关,应启用带有时间戳的GC日志记录,并将减速/ CPU使用量下降与Young / Full GC集合的时间相关联。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM