我可以设置Java VM可用的线程/ CPU数量吗?

问题描述 投票:10回答:6

我想限制Java VM可用的线程/进程数,类似于设置可用内存的方式。我希望能够指定它只使用1个线程或任意数字。

注意:我无法在代码中设置它,因为我想限制的代码是一个我无法修改源代码的库。因此,它必须是强加于虚拟机级别的硬限制。 (或者,如果您可以对应用程序本身施加可以覆盖库的线程限制?)

注意2:这是一个性能测试,用于限制我想要测试的库,以查看当它可以访问不同数量的CPU /线程时它的性能。

谢谢!

java multithreading jvm
6个回答
2
投票

没有VM标志或属性来控制Java可用的CPU数量,即Runtime.availableProcessors()返回的数量。

在Windows和Solaris上,如果设置了进程关联掩码,它也会影响Runtime.availableProcessors()。这在Linux上不起作用,请参阅JDK-6515172。不幸的是,修复程序仅针对Java 10,但建议的修补程序包含在错误讨论中。

使用LD_PRELOAD补丁或操作系统级别的技巧也可以解决Linux的问题,请参阅this question中的详细信息。


1
投票

如果你在Linux上,只需将java启动器包装在numactl / taskset命令中。这允许JVM生成任意数量的线程,但是在固定数量的物理内核上调度它们。

其他操作系统也可以使用类似的工具。


1
投票

我建议您可以实现并安装自己的SecurityManager,它跟踪创建的线程数,并在达到最大值时抛出错误。

根据this question接受的答案,每次创建/启动新线程时都会检查带有“modifyThreadGroup”目标的RuntimePermission

更新

SecurityManager的第一种方法可能是这样的:

class MySecurityManager extends SecurityManager
{
    private final int maxThreads;

    private int createdThreads;

    public MySecurityManager(int maxThreads)
    {
        super();
        this.maxThreads=maxThreads;
    }

    @Override
    public void checkAccess(Thread t)
    {
        // Invoked at Thread *instantiation* (not at the start invokation).
        super.checkAccess(t);

        // Synchronized to prevent race conditions (thanks to Ibrahim Arief) between read an write operations of variable createdThreads:
        synchronized(this)
        {
            if (this.createdThreads == this.maxThreads)
            {
                throw new Error("Maximum of threads exhausted");
            }
            else
            {
                this.createdThreads++;
            }
        }
    }
}

对于corse,必须进行进一步的测试以保证始终允许系统线程。并且仍然认为该算法在线程结束时不会减少计数。


1
投票

尝试使用“亲和力”为Windows用户运行程序。

例如:当你需要1个核心时,你应该运行:“start / affinity 1 java Test”,而不是运行“java Test”;当你需要2个核心时,“start / affinity 3 java Test”; ....使用的参数应遵循以下形式:

https://blogs.msdn.microsoft.com/santhoshonline/2011/11/24/how-to-launch-a-process-with-cpu-affinity-set/

您可以使用“System.out.println(Runtime.getRuntime()。availableProcessors());来检查。


0
投票

作为最后的手段,我可​​以将Java VM在任务管理器中的亲和力设置为仅使用1个(或更多)CPU。 (这当然仍然允许1个CPU上的多个线程,但如果没有其他任何更好的想法,它可能是我想要的最接近的东西)


0
投票

JVM中的CPU限制问题在Java 10中得到解决,并从build 8u191向后移植到Java 8:

-XX:ActiveProcessorCount=2
© www.soinside.com 2019 - 2024. All rights reserved.