我们有一个68级的大班,22名双人,还有4名成员。 e.g
Class A{
public int i1
public int i2
public int i3
....
public Order order1
public Order order2
...
public double..
}
1:i1,i2,i3的记忆是否持续不断?
2:对于A类,它是否存储指向order1&的指针。订单2,或者它存储订单1和1的内容。订单2?
还有另一个B类,其成员为A数组,有365 A.所以B的内存可能非常大。我担心的是如果B的大小太大,我们可能会丢失大量的2级缓存并降低性能。我们主要将i1的值相加,并将i2的值相加,并将i3的值相加等。 例如,如果所有365 A的总和i1,那么所有这些365A的i1将不会连续地存在于存储器中。所以我们可能会丢失一些缓存并获得不良的性能。
我正在考虑使用B类但删除A类,并将A中的所有元素移到B中,这样我们就可以得到
Class B {
public array_of_i1
public array_of_i2
..
}
这样,当我计算i1或i2的总和时,那么所有的i1或i2都坐在一起,所以也许我们可以获得性能提升?
由于班级很大,我想在改变之前寻找你的意见。
答案 0 :(得分:3)
它通常是连续的,但它取决于您使用的JVM。
一个复杂因素是运行时 Java对象的内存结构是 不是由虚拟机强制执行的 规范,这意味着 虚拟机提供商可以 随心所欲地实施它们。该 结果就是你可以写一个 class,以及该类的实例 一个VM可以占用不同的数量 内存比实例的内存 在另一个VM中运行时的类。
至于具体布局,
为了节省一些记忆,太阳 VM不会布置对象的属性 以相同的顺序声明它们。 相反,属性是有组织的 在内存中按以下顺序:
- 双打和渴望
- ints and floats
- 短裤和字符
- 布尔和字节
- 引用
醇>
(来自http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html)
他还包括如何处理继承的类。
答案 1 :(得分:3)
JLS没有强烈指定对象的确切大小,因此在JVM实现之间可能会有所不同(尽管您可以推断出一些较低的边界,即一个整数必须至少< / em> 32位)。
在Sun的JVM中,整数需要32位,双精度需要64位,对象引用需要32位(除非你在64位JVM上运行并且指针压缩被禁用)。然后对象本身有一个2字的标题,整个内存大小与8个字节的倍数对齐。
总的来说,这个对象应该采用8 * ceil((8 + 68 * 4 + 22 * 8 + 4 * 4) / 8)
= 10448字节,如果我没有忘记考虑某些事情(这是完全可能的),并且如果你在32位机器上运行。
但是 - 如上所述,你不应该过分依赖它,因为它没有在任何地方指定,将在实现之间和不同平台上有所不同。与性能相关的指标一样,关键是编写干净的代码,测量影响(在这种情况下使用分析器查看内存使用情况和执行时间),然后根据需要进行优化。
从宏观角度看,表现才真正重要;在设计对象模型时担心L2缓存丢失实际上是错误的方法。
(一个有94个字段的课程几乎肯定不是一个干净的设计,所以你考虑重构它是正确的......)
答案 2 :(得分:1)
首先,在您开始任何工作之前,您是否已将自己的应用程序分析出来?缓存未命中是否会导致瓶颈?
您的表现要求是什么? (注意:'尽快'不是要求*)
答案 3 :(得分:0)
答案 4 :(得分:0)
或者您可以更改结构以使用较小的类,将紧密循环中运行的内容保持在一起趋势以提高缓存命中率(iff这是您的性能瓶颈)。