lev*_*tov 13 java performance garbage-collection jvm jvm-hotspot
想象一下,我定义了一个包含许多引用字段的类(而不是使用引用数组Object[]),并在应用程序中大量实例化该类.
它是否会影响Hotspot JVM中垃圾收集器的性能,当它遍历堆来计算可达对象时?或者,对于某些JVM的内部数据结构或类元数据,它可能导致显着的额外内存消耗?或者,它是否会以某种其他方式影响应用程序的效率?
那些特定于Hotspot中的每个垃圾收集器算法的方面,或者Hotspot的机制的那些部分是否被所有垃圾收集器共享和使用?
Ale*_*lev 14
让我重新解释一下这个问题."下面有A级或B级更好吗?"
class A {
Target[] array;
}
class B {
Target a, b, c, ..., z;
}
Run Code Online (Sandbox Code Playgroud)
尽管存在通常的可维护性问题......从VM的角度来看,给定已解析的对B类的引用,它需要一个取消引用才能到达Target字段.在A类中,它需要两个差异,因为我们还需要读取数组.
在两种情况下对象引用的处理略有不同:在类A中,VM知道存在连续的引用数组,因此它不需要知道任何其他内容.在B类中,VM必须知道哪些字段是引用(例如,因为可能存在非引用字段),这需要在类元数据中维护oop映射:
// InstanceKlass embedded field layout (after declared fields):
...
// [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size
// The embedded nonstatic oop-map blocks are short pairs (offset, length)
// indicating where oops are located in instances of this
Run Code Online (Sandbox Code Playgroud)
请注意,虽然有足迹开销,但它不太重要,除非你有很多这种奇怪形状的类,但即便如此,成本也是每个类,而不是每个实例.
Oop-map是在类解析期间通过共享运行时代码构建的.遍历特定对象的"oop"-s的访问者查看那些oop-map以查找引用的偏移量,并且该代码也是共享运行时的一部分.因此,此开销与GC实现无关.
绩效考虑因素:
因此,询问单独字段与数组的GC /运行时处理的差异可能没什么意义.照顾参考地点很可能会带来更大的收益.这会将规模提升到B类,并带来相关的可维护性开销 - 正如相当多的性能技巧所做的那样.
| 归档时间: |
|
| 查看次数: |
654 次 |
| 最近记录: |