usenuma做了什么?(2012-03-14)

16
Kris Mok, Software Engineer, Taobao @rednaxelafx 莫莫 /“ 莫莫”

Upload: kris-mok

Post on 15-Jan-2015

2.343 views

Category:

Technology


10 download

DESCRIPTION

UseNUMA在JDK6/Linux上的实现

TRANSCRIPT

Page 1: UseNUMA做了什么?(2012-03-14)

Kris Mok, Software Engineer, Taobao@rednaxelafx莫枢 /“ 撒迦”

Page 2: UseNUMA做了什么?(2012-03-14)

UseNUMA 做了什么?

JDK6/Linux 中的 HotSpot VM 实现

阿里巴巴集团 - 技术共享平台 -

核心系统研发 - 专用计算组莫枢(撒迦)2012-03-14

Page 3: UseNUMA做了什么?(2012-03-14)

UseNUMA 的有效范围• JDK 6 / Linux 上:

– 硬件是 NUMA 架构的; BIOS 打开了 NUMA 选项– Xen 等虚拟层的 NUMA 选项打开(如有)– 操作系统的 NUMA 选项打开

• 请检查 /sys/devices/system/node/• 可通过 numastat的输出判断 JVM 以下各层是否都设置正确

– 只要有设置不正确的就只能看到 1个 node

– libnuma.so.1 存在并且可加载• 无法加载到该库会使 UseNUMA = false

– -XX:+UseParallelGC / -XX:+UseParallelOldGC• JDK6 的 HotSpot VM 的其它 GC 未实现 NUMA 支持

– -XX:+ForceNUMA• 强制打开 UseNUMA,但并不代表就会变快

Page 4: UseNUMA做了什么?(2012-03-14)

UseNUMA 的有效范围(续)

$ numastat node0 node1numa_hit 619315854 14453914507numa_miss 75245098 9049098780numa_foreign 9049098780 75245098interleave_hit 657266 752980local_node 618174068 14452713656other_node 76386884 9050299631

Page 5: UseNUMA做了什么?(2012-03-14)

UseNUMA 的有效范围(续)

• 确认 UseNUMA 的开启:– jinfo –flag UseNUMA <pid>• 正确开启时显示: -XX:+UseNUMA• 未开启时显示: -XX:-UseNUMA

Page 6: UseNUMA做了什么?(2012-03-14)

UseNUMA 的有效范围(续)

• Bug 7060836:– RHEL 5.5 and 5.6 don't support UseNUMA

because the locality group id implementation is done via a call to sched_getcpu(), which was introduced in only in recent versions of libc. In the case of RHEL 5.5 and 5.6, Hotspot cannot find sched_getcpu and UseNUMA is disabled.

– RHEL 5.4 同样受影响– 在 JDK7u2 有修复;淘宝 JDK6u32 有移植该修复

Page 7: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现• JVM 的 GC heap 初始化时

– eden 空间的布局会适应 NUMA 拓扑• 由 MutableNUMASpace实现• 根据 locality group 将地址空间划分为若干块• 每个 locality group 有一块独立的分配空间

– 称为 LGRPSpace

• 每个 LGRPSpace所包含的 page 在指定的 locality group 上分配物理内存– MutableNUMASpace::bias_region()– => numa_tonode_memory()

– 其它空间不受 NUMA 拓扑影响• survivor spaces 、 old generation 、 permanent

generation 默认使用 interleaved 方式分配内存,不偏向任何locality group

实验例子参考资料

Page 8: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)普通的 ParallelScavengeHeap布局Heap

PSYoungGen total 150208K, used 59114K [0x0000000758600000, 0x0000000762da0000, 0x0000000800000000) eden space 128768K, 38% used [0x0000000758600000,0x000000075b6ac8d8,0x00000007603c0000) from space 21440K, 43% used [0x00000007603c0000,0x0000000760cce0d0,0x00000007618b0000) to space 21440K, 0% used [0x00000007618b0000,0x00000007618b0000,0x0000000762da0000) ParOldGen total 343296K, used 0K [0x0000000609200000, 0x000000061e140000, 0x0000000758600000) object space 343296K, 0% used [0x0000000609200000,0x0000000609200000,0x000000061e140000) PSPermGen total 21248K, used 16956K [0x0000000604000000, 0x00000006054c0000, 0x0000000609200000) object space 21248K, 79% used [0x0000000604000000,0x000000060508f390,0x00000006054c0000)

Page 9: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)604000000 default anon=5312 dirty=5312 N1=5312

6054c0000 default

609200000 default anon=85824 dirty=85824 N1=85824

61e140000 default

758600000 default anon=42912 dirty=42912 N1=42912

762da0000 default (日志来自 /proc/<pid>/numa_maps )

Permanent Generation (commited)

Permanent Generation (reserved)

Old Generation (reserved)

Young Generation (reserved)

Young Generation (commited)

Old Generation (commited)

Page 10: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)使用 -XX:+UseNUMA的ParallelScavengeHeap布局

Heap PSYoungGen total 150208K, used 24082K [0x0000000758600000, 0x0000000762da0000, 0x0000000800000000) eden space 128768K, 11% used [0x0000000758600000,0x000000075d122cc8,0x00000007603c0000) lgrp 0 space 64384K, 4% used [0x0000000758600000,0x0000000758883d98,0x000000075c4e0000) local/remote/unbiased/uncommitted: 0K/0K/0K/0K, large/small pages: 0/0 lgrp 1 space 64384K, 19% used [0x000000075c4e0000,0x000000075d122cc8,0x00000007603c0000) local/remote/unbiased/uncommitted: 0K/0K/0K/0K, large/small pages: 0/0 from space 21440K, 41% used [0x00000007603c0000,0x0000000760c7e0b0,0x00000007618b0000) to space 21440K, 0% used [0x00000007618b0000,0x00000007618b0000,0x0000000762da0000) ParOldGen total 343296K, used 0K [0x0000000609200000, 0x000000061e140000, 0x0000000758600000) object space 343296K, 0% used [0x0000000609200000,0x0000000609200000,0x000000061e140000) PSPermGen total 21248K, used 16790K [0x0000000604000000, 0x00000006054c0000, 0x0000000609200000) object space 21248K, 79% used [0x0000000604000000,0x00000006050659a0,0x00000006054c0000)

Page 11: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)604000000 interleave=0-1 anon=4185 dirty=4185 N0=2093 N1=2092

6054c0000 default

609200000 interleave=0-1

61e140000 default

758600000 bind=0 anon=16096 dirty=16096 N0=16096

75c4e0000 bind=1 anon=16096 dirty=16096 N1=16096

7603c0000 interleave=0-1 anon=2239 dirty=2239 active=2215 N0=1120 N1=1119

7618b0000 interleave=0-1

762da0000 default

Permanent Generation (commited)

Permanent Generation (reserved)

Old Generation (commited)

Old Generation (reserved)

LGRPSpace (lgrp_id=0)

LGRPSpace (lgrp_id=1)

Survivor Space 0 (commited)

Survivor Space 1 (commited)

Young Generation (reserved)

使用 -XX:+UseNUMA的ParallelScavengeHeap布局

Page 12: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)• Java 线程启动时– 记录线程所在的 CPU 对应的 locality group

id

• 外部线程 attach 到 JVM 时– 同上

Page 13: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)• Java 程序正常运行时– 每个 locality group 的线程在各自的LGRPSpace 中分配空间• 每个线程在自己的 TLAB 里分配空间给 Java 对象• 每个线程的 TLAB 都只在所属的 locality group 的LGRPSpace 里分配– MutableNUMASpace::allocate()– 每次分配 TLAB 会重新记录当前线程的 lgrp_id ,以便适

应线程在不同 locality group 之间的迁移• 没有“ shared eden”

– 每当有 LGRPSpace 填满了就触发一次 minor GC

Page 14: UseNUMA做了什么?(2012-03-14)

UseNUMA 的实现(续)• ( Linux 上不支持) NUMA 拓扑发生变化

时– 所有 Java 线程的 locality group id 被清除• MutableNUMASpace::update_layout()

– 每个线程在之后第一次尝试分配空间时重新记录 local group id• MutableNUMASpace::allocate()• MutableNUMASpace::cas_allocate()

Page 15: UseNUMA做了什么?(2012-03-14)

QUESTIONS?

Page 16: UseNUMA做了什么?(2012-03-14)

Kris Mok, Software Engineer, Taobao@rednaxelafx莫枢 /“ 撒迦”