做网站的软件名字全拼,现在流行的网站制作工具,如何做电视剧的短视频网站,石家庄网络seo推广当实例化一个Java类时#xff0c;运行时环境必须为相关实例分配存储空间#xff0c;在JRE中此存储空间分配操作是由内存管理器实现的#xff08;其实是JVM的垃圾回收器#xff09;#xff0c;由于内存管理器通常使用与运行时目标语言不同的语言编写#xff08;例如#…当实例化一个Java类时运行时环境必须为相关实例分配存储空间在JRE中此存储空间分配操作是由内存管理器实现的其实是JVM的垃圾回收器由于内存管理器通常使用与运行时目标语言不同的语言编写例如Java 以 JVM 为目标而 HotSpot JVM 是用 C 编写的因此接口会变得更加模糊。而这种操作成本是相当高的并且内存管理器也必须应对多线程场景下进行内存请求多压力。为了使Java程序的运行效率尽可能接近C等语言的运行效率针对JVM的内存管理器的执行效率需要进行优化。
1.优化方法
优化方法如允许线程分配整个内存块以满足其需求并且只传输到 VM 以获取新块。在 Hotspot 中这些块称为线程本地分配缓冲区 (TLAB)并且有一个复杂的机制来支持它们。请注意TLAB 在时间意义上是线程本地的这意味着它们像缓冲区一样接受当前分配。它们仍然是 Java 堆的一部分线程仍然可以将对新分配对象的引用写入 TLAB 之外的字段等等。
所有已知的 OpenJDK GC 都支持 TLAB 分配。VM 代码的这一部分在它们之间基本是共享的。所有 Hotspot 编译器都支持 TLAB 分配因此您通常会看到如下所示的对象分配生成代码
0x00007f3e6bb617cc: mov 0x60(%r15),%rax ; TLAB current
0x00007f3e6bb617d0: mov %rax,%r10 ; tmp current
0x00007f3e6bb617d3: add $0x10,%r10 ; tmp 16 (object size)
0x00007f3e6bb617d7: cmp 0x70(%r15),%r10 ; tmp tlab_size?
0x00007f3e6bb617db: jae 0x00007f3e6bb61807 ; TLAB is done, jump and request another one
0x00007f3e6bb617dd: mov %r10,0x60(%r15) ; current tmp (TLAB is fine, alloc!)
0x00007f3e6bb617e1: prefetchnta 0xc0(%r10) ; ...
0x00007f3e6bb617e9: movq $0x1,(%rax) ; store header to (obj0)
0x00007f3e6bb617f0: movl $0xf80001dd,0x8(%rax) ; store klass to (obj8)
0x00007f3e6bb617f7: mov %r12d,0xc(%rax) ; zero out the rest of the object2.指针碰撞分配
分配路径内联在生成的代码中因此不需要调用 GC 来分配对象。如果我们请求分配耗尽了 TLAB 的对象或者对象足够大而无法放入 TLAB那么我们将采取“慢速路径”要么在那里满足分配要么返回新的 TLAB。请注意最常见的“正常”路径只是将对象大小添加到 TLAB 当前光标然后继续。
这就是为什么这种分配机制有时被称为“指针碰撞分配”。指针碰撞需要分配一块连续的内存但这又带来了堆压缩的需要。请注意 CMS 如何在“老”代中进行空闲列表分配从而实现并发清除但它压缩了STW情况下堆中的“年轻代”集合这受益于指针碰撞分配年轻代集合中幸存下来的对象数量要少得多这就是空闲列表分配的代价。
为了进行实验我们可以使用 -XX:-UseTLAB 关闭 TLAB 功能。然后所有分配都将进入本机方法通常不建议这么做如下所示
- 17.12% 0.00% org.openjdk.All perf-31615.map- 0x7faaa3b2d125- 16.59% OptoRuntime::new_instance_C- 11.49% InstanceKlass::allocate_instance2.33% BlahBlahBlahCollectedHeap::mem_allocate ---- entry point to GC0.35% AllocTracer::send_allocation_outside_tlab_event3.总结
TLAB 是内存分配机制的主力它们消除了分配器的并发瓶颈提供了廉价的分配路径并全面提高了性能。有趣的是使用 TLAB 会导致更频繁的 GC 只是因为内存分配非常便宜相反在任何内存管理器实现中没有快速分配路径肯定会隐藏内存回收性能问题从而严重的影响JVM的性能。