【问题标题】:Do specialized Optional types (OptionalInt, OptionalDouble, etc) perform a heap allocation?专门的可选类型(OptionalInt、OptionalDouble 等)是否执行堆分配?
【发布时间】:2015-10-21 20:09:30
【问题描述】:

在热代码路径中调用返回专用 Optional 类型的函数是否会以增加 GC 压力为代价,而不是返回原始值以指示不存在(例如Integer.MIN_VALUE)?

编辑

我不只是假设它们会像任何其他类一样执行堆分配的原因是 Optional 等人是“value-based classes”,这似乎暗示它们的行为可能与传统类不同在幕后。

【问题讨论】:

  • 它们是对象,行为与任何其他对象一样。
  • 这取决于你在做什么。为什么不使用和不使用 Optional 对用例进行基准测试?我很确定它不会成为您代码中的瓶颈...

标签: java java-8


【解决方案1】:

在热代码路径中使用时,调用返回专用 Optional 类型的函数是否会以增加 GC 压力为代价

这取决于™。 一般 Optional 类型只是常规对象,因此是堆分配的。但在特定情况下,JIT 编译器可能将它们分解为它们的字段(即它们持有的值)并将它们放入堆栈。

如果escape analysis 可以确定对象没有全局逃逸到堆上,就会发生这种情况。

似乎还有其他隐藏在标志后面的实验性优化(-XX:+AggressiveUnboxing-XX:+AggressiveOpts 的一部分)。据我了解,他们可能会破坏Integer.valueOf(int) 的身份保证,因此不完全符合规范。

切线:实验/研究Graal compiler 甚至更进一步,partial escape analysis 可以推迟分配到对象确实逃逸的那些代码路径,而当它们没有逃逸时,它们会在堆栈上进行标量分解。这还不是常规 VM 的一部分,主要由在 JVM 上运行的非 Java 语言使用,例如 JRuby 和 Nashorn。

由于所有这些都是运行时优化,因此无法保证会发生这种情况。因此,您必须使用诊断标志来衡量效果或跟踪编译器决策。

我不只是假设他们会像任何其他类一样执行堆分配的原因是 Optional 等是“基于值的类”

我认为目前这些属性只是为了确保对象是不可变的和线程安全的。我不知道 EA 之外的任何优化是否利用了互换性属性。

我怀疑规范语言的主要目的是为正确的value-types 提供前向兼容性,当它们最终作为project valhalla 的一部分到达Java 时。

遵循这些规则也使逃逸分析/堆栈分配变得更容易。

【讨论】:

    【解决方案2】:

    是的。

    这些类扩展Object,因此是引用类型。它们将占用堆空间,类似于您使用以前可用的包装类(如 Integer)。

    此外,这些类型鼓励使用 lambda 表达式,它们本身会创建匿名类型的新实例。根据 lambdas “关闭”的值,您最终可能会导致这些对象也引用其他对象,这会对 GC 产生一些影响。

    因此,在您希望避免实例化类实例、装箱/拆箱等出于性能原因的地方,您仍然希望避免使用这些可选类型。

    更新

    Java 8 引入了基于值的类的概念,作为 Java 10 的“值类型”的一个有希望的垫脚石。

    InfoQ:让我们谈谈 Optional 作为原型值类型的可能性。

    Goetz:对于将 Java 8 引用类型迁移到 Java 10 值类型的想法,可能存在一些轻微的乐观情绪。基本上,我们已经奠定了基础,表明开发人员不能依赖某些属性(例如身份检查)对于将来可能成为值类型的类型必然是正确的。这种迁移在实践中是否被证明是可行的还有待观察。

    http://www.infoq.com/articles/Java-9-and-Beyond-Goetz-Rose-Interview

    所以从 Java 8 开始,这些类仍然像普通类一样工作,但是现在通过对它们创建某些限制,当 Java 10 获得该功能时,它们可以转换为值类型。

    假设它最终发生,我发现将这些类型转换为值类型有两个主要优点:

    1. 提高了性能,因为您不需要使用堆空间。
    2. 值类型永远不会为空,因此如果您有一个 OptionalDouble 类型的字段并且您从未对其进行初始化,那么您仍然不会出现空指针异常。

    无耻插件:我在我编写的库中利用了 C# 中结构类型的这些属性为 Maybe<> 类型。

    【讨论】:

    • 请看我的编辑。可选类型是基于值的类,这似乎意味着它们的分配方式不同或可以利用某些优化。
    • @w.brian:感谢您对此进行扩展。查看我的更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2010-10-22
    • 2022-10-04
    相关资源
    最近更新 更多