Shenandoah收集器在JDK21及主流OpenJDK发行版中不原生支持NUMA感知,未实现线程绑定、本地内存优先分配或NUMA-aware调度,其所有GC操作基于统一堆视图,依赖外部numactl等工具手动优化。
Shenandoah收集器本身不直接感知或原生适配NUMA拓扑,它在多核处理器系统上运行时,默认按通用并发模型调度线程,不会主动将GC工作线程绑定到特定NUMA节点、也不会优先分配本地内存给对应CPU核心。这与G1在JDK 14+中明确增强的NUMA支持形成对比。
截至JDK 21(LTS)及当前主流OpenJDK发行版(如Red Hat build、Eclipse Temurin),Shenandoah收集器没有实现NUMA-aware的内存分配策略或线程亲和性调度。它的Region分配、对象复制、转发指针更新等关键操作,均基于统一堆视图进行,不区分本地内存与远程内存访问代价。
mbind()、numactl相关API控制页放置位置虽然Shenandoah不主动适配NUMA,但在真实多节点服务器上,NUMA特性仍会间接影响其行为:
若需在NUMA系统中发挥Shenandoah最佳性能,需依赖外部协同配置,而非收集器自身能力:
numactl --cpunodebind=0 --membind=0 java ...将整个JVM进程限定在单个NUMA节点,消除跨节点访问-XX:+UseLargePages减少TLB miss,缓解远程内存访问的地址翻译开销-XX:ParallelGCThreads和-XX:ConcGCThreads使其不超过单节点CPU核心数,避免线程跨节点迁移/sys/devices/system/node/下各节点内存使用与跨节点访问计数(如numastat输出),验证是否出现显著remote node page allocationG1自JDK 14起通过-XX:+UseNUMA参数启用显式NUMA优化:自动为每个节点维护独立的Remembered Set、按节点划分年轻代Eden区、并尝试将Region分配与创建线程所在节点对齐。Shenandoah目前无对应开关或内部模块,其设计重心始终放在“停顿时间与堆大小解耦”这一核心目标上,NUMA适配尚未纳入官方路线图。