java:类成员的内存如何分配?

时间:2010-11-11 14:17:00

标签: java memory-management

我们有一个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都坐在一起,所以也许我们可以获得性能提升?

由于班级很大,我想在改变之前寻找你的意见。

5 个答案:

答案 0 :(得分:3)

它通常是连续的,但它取决于您使用的JVM。

  

一个复杂因素是运行时   Java对象的内存结构是   不是由虚拟机强制执行的   规范,这意味着   虚拟机提供商可以   随心所欲地实施它们。该   结果就是你可以写一个   class,以及该类的实例   一个VM可以占用不同的数量   内存比实例的内存   在另一个VM中运行时的类。

至于具体布局,

  

为了节省一些记忆,太阳   VM不会布置对象的属性   以相同的顺序声明它们。   相反,属性是有组织的   在内存中按以下顺序:

     
      
  1. 双打和渴望
  2.   
  3. ints and floats
  4.   
  5. 短裤和字符
  6.   
  7. 布尔和字节
  8.   
  9. 引用
  10.   

(来自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)

  1. 这将取决于实现。
  2. 是的,它存储了指针。对象将驻留在其他地方。

答案 4 :(得分:0)

  1. 一般来说,是的。但我认为你不一定要依赖它。这种低级别的东西的语言错误。
  2. 指针,但我不确定为什么重要。
  3. 在出于性能原因进行重大更改之前的配置文件。我认为第二个是 cleaner 。你宁愿为你的求和做一个简单的数组循环吗?
  4. 或者您可以更改结构以使用较小的类,将紧密循环中运行的内容保持在一起趋势以提高缓存命中率(iff这是您的性能瓶颈)。