我的JVM在带有openJDK 1.7.0_51 64Bit的CentOS 6.0上运行时出现问题。 我的系统是一个4核系统,配备8GB Ram。
我正在运行我自己编写的Java多线程应用程序。它应该将大量数据插入NoSQL数据库。 为此,我使用java.concurrent.Executors中的“CachedThreadPoolExecutor”生成4个线程。
我实例化了4个实现“Runnable”接口的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,它将在Threadpool中生成4个Threads。我假设JVM或我的操作系统足够聪明,可以在我的所有内核上安排这些线程。 但是,只有我的cpu的一个核心工作在100%,其他核心几乎无所事事。
我在代码中做错了什么,或者这是一个JVM / OS问题。如果是这样,我能做些什么吗? 仅在1个核心上运行此应用程序极其缓慢了整个应用程序。
非常感谢帮助:)
答案 0 :(得分:4)
请记住它的操作系统,而不是负责CPU亲和力的JVM - 这就是为什么我建议你先弄清楚你有多少CPU然后使用schedutil来配置某个进程的处理器关联。
cpu info - 使用以下三个中的一个
/proc/cpuinfo
lscpu
nproc
安装计划以配置处理器关联性
yum install schedutils
您可以通过schedutils分配cpu affinity,如下所示(2是第二个procccor,23564是进程ID):
taskset -c 2 -p 23564
答案 1 :(得分:1)
调度线程不是JVM活动,而是操作系统活动。如果操作系统发现线程彼此独立,可以单独执行,然后将其安排在另一个核心上。
我不确定schedutils但我认为它适用于应用程序级别(它允许你设置cpu亲和力,但最后的决定是由OS采取的)
关于使用内核的一件事是OS调度程序在新内核上安排新进程,因为每个进程都有自己独立于其他进程的进程区域(因此它们可以平行执行而不受任何阻碍)尝试为每个线程创建新进程,以帮助提高cpu利用率(使用更多内核),但也有缺点,每个进程都创建自己的进程区域,因此每个进程都需要额外的内存(对于每个线程)在你的情况下)如果你有足够的可用内存,那么你可以试试这个。
如果它只是一个Linux操作系统,那么“sar”命令足以监控每个核心的CPU利用率(sar是linux中的基础包,几乎所有实用程序都使用'sar',因此系统上的开销会更少)。
答案 2 :(得分:0)
如果您的环境是虚拟的,或者使用诸如docker之类的特殊cpu调度,则无法让Java自动使用来查找可用的许多内核并全部使用它们。您必须通过
指定要使用多少个内核在JDK> = 10上,使用以下JDK选项:
-XX:ActiveProcessorCount = 2
在JDK> = 8上,使用以下JDK选项:
-XX:+ UnlockExperimentalVMOptions> -XX:ActiveProcessorCount = 2