我的JVM在64位openJDK 1.7.0_51的CentOS 6.0上运行时出现了问题。我的系统是一个带有8 8GB内存的4核系统。
我正在运行自己编写的Java多线程应用程序。它应该将大量数据插入到NoSQL数据库中。为此,我使用来自java.concurrent.Executors的"CachedThreadPoolExecutor“生成了4个线程。
我实例化了实现"Runnable“接口的4个Worker。然后,我使用线程池执行Thread。下面是我的代码:
public void startDataPump(int numberOfWorkers){
//class "DataPump" implements runnable
for (int i = 0; i < numberOfWorkers; i++){
DataPump pump = new DataPump();
//"workerList" contains all workers and is a simple arrayList to keep track of the workers
workerList.add(pump);
//"workers" is the thradpool that has been
//initialized earlier with "Executors.newCachedThreadPool()
workers.execute(pump);
}
}当运行它时,使用参数4,它将在线程池中产生4个线程。我假设JVM或我的操作系统足够智能,可以在我的所有内核上调度这些线程。然而,我的cpu中只有一个核心在100%地工作,其他的几乎都是空闲的。
我是否在代码中做错了什么,或者这是JVM/OS问题。如果是这样,我能做些什么呢?只在一个核心上运行这个应用程序是极端的,减慢了整个应用程序的速度。
非常感谢您的帮助:)
发布于 2014-01-23 01:53:14
请记住,是操作系统而不是JVM负责CPU亲和性-这就是为什么我建议您首先计算出您有多少CPU,然后可能使用schedutils为某个进程配置处理器亲和性。
cpu信息-使用以下三种之一
/proc/cpuinfo
lscpu
nproc安装schedutils以配置处理器亲和性
yum install schedutils 您可以通过schedutils分配cpu亲和性,如下所示(2是第二个proceccor,23564是进程id):
taskset -c 2 -p 23564发布于 2014-01-23 13:29:57
调度线程不是JVM的活动,而是OS,activity.if操作系统发现线程是相互独立的,可以单独执行,然后在另一个内核上调度它。
我不确定schedutils,但我认为它在应用程序级别工作(它允许您设置cpu亲和性,但最后的决定由操作系统决定)
使用内核的一件事是OS调度程序在新的内核上调度新的进程,因为每个进程都有独立于其他进程的自己的进程区域(因此它们可以在没有任何障碍的情况下并行执行)。
试着为每个线程创建新的进程,这将有助于提高cpu利用率(使用更多的内核),但它也有缺点,每个进程都会创建自己的进程区域,因此每个进程(对于您的情况中的每个线程)都需要额外的内存。如果您有足够的可用内存量,那么可以尝试这个进程。
如果它只是一个linux操作系统,那么"sar“命令就足以监视每个核心cpu利用率(sar是linux中的基本软件包,几乎所有实用程序都使用”sar“,因此系统开销会更小)。
发布于 2019-08-28 08:05:01
如果您的环境是虚拟的,或者是像docker这样的特殊cpu调度,那么就没有办法让Java自动使用查找许多可用内核并将它们全部使用。您必须指定要通过以下方式使用的内核数量
在JDK >= 10上,使用以下JDK选项:
-XX:ActiveProcessorCount=2
在JDK >= 8上,使用以下JDK选项:
-XX:+UnlockExperimentalVMOptions > -XX:ActiveProcessorCount=2
https://stackoverflow.com/questions/21289922
复制相似问题