【问题标题】:Which design consumes less memory?哪种设计消耗更少的内存?
【发布时间】:2016-01-21 19:46:30
【问题描述】:

如果我有一个 interface In1 和两个实现 In1 的类 c1,c2
如果我有两个类x1,x2,它们只有自己的方法

其行为方式与c1,c2相同,例如:

In1  i1 = new c1();
i1 = new c2();

X1 x1 = new x1();
X2 x2 = new x2();

以上哪个消耗更多内存

【问题讨论】:

  • 除非你有十亿个这样的对象,否则这不太重要。在这种情况下,差异将是内存的一小部分。
  • Java 也可以在内存有限的嵌入式系统中运行。

标签: java memory


【解决方案1】:

假设实现在其他方面相同,则无论类是否实现接口都不会显着改变运行时内存需求。

专门查看您的代码

In1  i1 = new c1();
i1 = new c2();

X1 x1 = new x1();
X2 x2 = new x2();

在第一个块中,一旦 i1 = new c2() 运行,您的 c1 实例将不再被引用。这使它有资格进行垃圾收集。该代码块与第二个代码块不同,因为第二个代码块维护对两个已分配对象的引用。

但是,如果您将第一个代码块重写为

In1  i1a = new c1();
In1  i1b = new c2();

无论有没有接口,您的内存需求都完全相同,因为您在相同的持续时间内持有对对象的引用。

更新

如果你标记你的类的方法final,我相信你会稍微节省内存分配,因为不需要vtable。在interfaces cannot be marked final 中声明的方法。

【讨论】:

  • 对于实现接口的类,Class 对象一侧可能会有一些小的内存增加。
  • @JiriTousek:我怀疑接口实现完全在编译时进行管理。如果类中的一个方法被标记为 final,那将减少一点内存占用,因为它将消除对 vtable 的需要。但是,最终方法不能与接口一起使用。我会更新我的答案以反映这一点。
  • 接口实现在运行时保留。如果不是,则运行时无法检查像 MyInterface bar = (MyInterface) foo 这样的运行时强制转换,并且您无法使用 Class.getInterfaces()Class.isAssignableFrom()
  • @JiriTousek:我认为这不是每个实例的开销,只是与类型相关的信息。当然它必须被存储,但它可能只是一些额外的字节,一次。
  • 同意,请参阅我的第一条评论:“Class 对象一侧的内存略有增加......”。可能有几个字节的恒定开销不会随着实例数量的增加而增加,但您不能称其为“完全相同”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 2013-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
相关资源
最近更新 更多