【问题标题】:Java Integer pool. Why?Java 整数池。为什么?
【发布时间】:2013-07-05 17:51:44
【问题描述】:

我到处读到,当你在 Java 中定义一个介于 -128 到 127 之间的整数时,它不会创建一个新对象,而是返回一个已经创建的对象。

除了让新手程序员将 Integer 对象与 == 进行比较以查看它们是否是相同的数字之外,我认为这样做没有任何意义,但我认为这很糟糕,因为他们认为他们可以比较任何 Integer使用==,并且还在教授任何编程语言的不良做法:将两个“不同”对象的内容与==进行比较。

这样做有什么其他原因吗?还是在设计 JavaScript 中的可选分号之类的语言(在我看来)时,这只是一个错误的决定?

编辑:我在这里看到他们解释了这种行为:Why does the behavior of the Integer constant pool change at 127?

我问的是为什么他们将其设计为具有这种行为,而不是为什么会发生这种行为。

【问题讨论】:

  • 当新对象不可变且可以共享时,分配新对象并占用内存感觉有点不必要。
  • 也许内存优化是一个答案,别想了。
  • 它节省内存,速度更快,并减少了垃圾收集器的压力。重用对象可以显着加快速度,因此某些选项会将整数缓存大小增加到 10,000 或 20,000。

标签: java object-comparison


【解决方案1】:

它被称为Flyweight pattern,用于最大限度地减少内存使用量。

这些数字很可能会被重复使用,并且像 Integer 这样的自动框类型是不可变的(请注意,这不仅适用于 Integer)。缓存它们可以减少实例数量,并减少 GC(垃圾收集)工作。

JLS 在5.1.7. Boxing Conversion 中特别提到:

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两次装箱转换的结果。 r1 == r2 总是如此。

理想情况下,装箱一个给定的原始值 p,总是会产生一个相同的引用。在实践中,使用现有的实现技术这可能是不可行的。上述规则是一种务实的妥协。上面的最后一个子句要求某些公共值总是被装箱到无法区分的对象中。实现可能会懒惰地或急切地缓存这些。对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

这可确保在最常见的情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有 char 和 short 值,以及 -32K 到 +32K 范围内的 int 和 long 值。

【讨论】:

  • 这不是第一个答案,而是一个更详细的答案。我不喜欢为我优化 Java 软件。我认为优化软件属于开发人员。我的意思是,他们改变了对象的工作方式,只是为了优化用户软件。如果开发人员想要优化它,他们应该努力制作自己的整数池。但这是我的看法:P
  • 现在我读到了你的拳击转换编辑并且更有意义了。 Java 在数以百万计的硬件差异非常大的设备下工作,因此他们不得不考虑不惜一切代价减少内存使用量。干得好Java:P
  • 我认为像 Java 这样的高级语言的整个 point 在可能的情况下向最终用户隐藏了血淋淋的细节;)但尤其是这一点......嗯,我可以去任何一种方式。
  • 如今,由于 Java 内存分配如此便宜 (ibm.com/developerworks/java/library/j-jtp09275/index.html),池化变得不那么重要了。 JVM 现在支持从 Java 7 和 Java SE 6u23 开始的逃逸分析,因此临时对象创建的影响更小(docs.oracle.com/javase/7/docs/technotes/guides/vm/…)。
【解决方案2】:

我认为创建任何对象都比从符号表中获取对象要花费更多时间。此外,如果我没记错的话,堆上的每个对象都会为头部占用 24 个字节的额外空间。现在,如果程序员编写他/她的程序,大多数操作都是在小整数(在本例中为小整数)上完成的。因此,它可以节省大量空间并稍微提高性能。

【讨论】:

  • 我很好奇.. 为什么是 24?在哪个 JVM 上?
  • 是的,现在有更多的意义......没有考虑记忆,真可惜哈哈:P 谢谢。
  • 我认为他们中的大多数。我不知道为什么标题正好是 24。我认为必须有一个签名或类似的东西。 + 如果总内存不能被 8 整除,则还添加填充(如果 Integer 是 int 的包装器 - 24 (header)+ 4 (int) + 4 (padding))
猜你喜欢
  • 2011-07-13
  • 2020-04-28
  • 2012-10-17
  • 2014-04-21
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 2011-03-18
相关资源
最近更新 更多