我正在开发一个 java 程序来创建一个非常大的 Neo4J 数据库。我使用 batchinserter 和 Executors.newFixedThreadPool 来加快速度。我的 Win2012R2 服务器在 NUMA 架构 中有 2 个 cpu(2x6 核心 + 2x6 超线程)和 256GB。我现在的问题是,我的进口商只使用 1 个 CPU(节点)。 是否可以仅通过一个 java 进程使用两个 NUMA 节点?
Java选项:-XX:+UseNUMA -Xmx64g -Xms64g
最佳答案
目前尚不清楚为每个节点分配了多少内存——是 256GB 还是 128GB?无论哪种方式,据我所知,将最大堆大小设置为小于分配给节点的内存量通常意味着应用程序保持与单个节点的关联。据我所知,在 Windows、Solaris 和 Linux 下都是如此。
即使您分配的 JVM 最大堆大小大于分配给节点的内存,如果您的堆没有增长到超过该大小,进程也不会溢出,因为 JVM 对象分配器将始终尝试创建一个新的对象在与创建线程相同的内存池中 - 并且包括新的线程对象。
NUMA 架构的主要设计目标是让不同的进程能够在不同的 CPU 上运行,每个 CPU 都具有本地内存访问权限,而不是让所有 CPU 争用相同的全局共享内存。让相同的进程在多个节点上运行不一定那么高效,除非您可以安排特定线程始终使用与特定节点关联的本地内存(线程关联)。否则,远程内存访问会减慢您的速度。
我怀疑要在您的示例中使用多个节点,您需要将不同的任务分配给不同的节点,或者跨多个节点并行执行同一任务。在后一种情况下,您需要确保每个节点在本地内存中都有相同数据的副本。有一些库可用于管理 Java 代码中的线程关联。
关于Java 仅将 2 个 CPU 中的 1 个用于 NUMA (Neo4J),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36127692/