繁体   English   中英

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

[英]java: How does the memory of a class member allocate?

我们有68个int的大类,22个double成员,还有4个成员。 例如

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和order 2的指针,还是存储订单1和order 2的内容?

还有另一个类B,该类的成员是A的数组,即365A。因此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都坐在一起,那么也许我们可以提高性能?

由于课程人数众多,我想在变更之前寻求您的意见。

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

一种复杂的情况是,虚拟机规范未强制执行Java对象的内存结构中的运行时,这意味着虚拟机提供程序可以根据需要实现它们。 结果是您可以编写一个类,并且在另一台VM中运行时,该同一个类中的该类实例所占用的内存量可以与该同一个类中的实例占用的内存量不同。

至于具体的布局,

为了节省内存,Sun VM不会按照声明对象的顺序来布置对象的属性。 而是按照以下顺序在内存中组织属性:

  1. 双打和多头
  2. 整数和浮点数
  3. 短裤和短裤
  4. 布尔值和字节
  5. 参考资料

(摘自http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

他还介绍了如何处理继承的类。

JLS并未严格指定对象的确切大小,因此这在JVM实现之间可能会有所不同(尽管您可以推断出一些下限 ,即整数必须至少为 32位)。

但是,在Sun的JVM中,整数占32位,双精度占64位,对象引用占32位( 除非您在64位JVM上运行并且指针压缩被禁用)。 然后,对象本身具有一个2字的标题,并且整个内存大小与8个字节的倍数对齐。

因此,总体而言,如果我没有忘记考虑某件事(完全有可能),则此对象应占用8 * ceil((8 + 68 * 4 + 22 * 8 + 4 * 4) / 8) = 10448个字节,并且如果您在32位计算机上运行。

但是 -如上所述,您不应真正依赖它,因为它没有在任何地方指定,并且在实现和不同平台上有所不同。 与使用性能相关的指标一样,关键是编写干净的代码,衡量影响(在这种情况下,使用探查器查看内存使用情况和执行时间),然后根据需要进行优化。

从宏观角度来看,性能才是真正重要的。 在设计对象模型时担心二级缓存丢失确实是错误的做法。

(而且具有94个字段的类几乎肯定不是一个干净的设计,因此您应该考虑对其进行重构...)

首先,在您从事任何工作之前,您是否已对应用程序进行了概要分析? 缓存未命中是否会造成瓶颈?

您对性能有何要求? (注:“越快越好” 心不是要求*)

  1. 那将取决于实现。
  2. 是的,它存储指针。 这些对象将驻留在其他位置。
  1. 一般来说,是的。 但我认为您不一定要依赖它。 该低级类型内容的语言错误。
  2. 指针,但是我不确定为什么这么重要。
  3. 由于性能原因,在进行重大更改之前进行配置。 我认为第二个虽然干净 您是否愿意为求和做一个简单的数组循环?

或者你可以改变使用较小的类结构,保持在一个紧凑的循环运行起来往往会提高缓存命中率(IFF这是你的性能瓶颈)的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM