Java 专用可选类型(Optionant、OptionalDouble等)是否执行堆分配?
当在热代码路径中使用时,返回专用可选类型的调用函数是否会以增加GC压力为代价,而不是返回一个原语值来表示不存在(Java 专用可选类型(Optionant、OptionalDouble等)是否执行堆分配?,java,java-8,Java,Java 8,当在热代码路径中使用时,返回专用可选类型的调用函数是否会以增加GC压力为代价,而不是返回一个原语值来表示不存在(Integer.MIN_value) 编辑 我之所以不认为它们会像任何其他类一样执行堆分配,是因为Optional等是“”,这似乎意味着它们在幕后的行为可能与传统类不同。是的 这些类扩展了对象,因此是引用类型。它们将占用堆空间,这与使用以前可用的包装器类(如Integer)类似 此外,这些类型鼓励使用lambda表达式,而lambda表达式本身会创建匿名类型的新实例。根据lambda“
Integer.MIN_value
)
编辑
我之所以不认为它们会像任何其他类一样执行堆分配,是因为Optional
等是“”,这似乎意味着它们在幕后的行为可能与传统类不同。是的
这些类扩展了对象,因此是引用类型。它们将占用堆空间,这与使用以前可用的包装器类(如Integer
)类似
此外,这些类型鼓励使用lambda表达式,而lambda表达式本身会创建匿名类型的新实例。根据lambda“close-over”的值,您可能最终会看到这些对象也引用了其他对象,这会对GC产生一些影响
因此,在出于性能原因希望避免实例化类实例、装箱/取消装箱等的地方,您仍然希望避免这些可选类型
更新
Java8引入了基于值的类的概念,作为Java10“值类型”的一个有希望的垫脚石
InfoQ:让我们谈谈可选作为原型值类型的可能性
Goetz:对于将Java8引用类型迁移到Java10值类型的想法,人们可能有点乐观。基本上,我们已经打下了基础,指出开发人员不能依赖某些属性(如身份检查),这些属性对于将来可能成为值类型的类型来说必然是真的。这种迁移在实践中是否可行还有待观察
因此,在Java8中,这些类仍然像普通类一样工作,但是通过对它们进行某些限制,有希望在Java10获得该功能时将它们转换为值类型
假设它最终发生了,我认为将这些类型转换为值类型有两个主要优势:
可选的
类型只是常规对象,因此是堆分配的。但在特定情况下,JIT编译器可能会将它们分解为字段(即它们所持有的值),并将它们放在堆栈上
如果可以确定对象没有全局转义到堆上,就会发生这种情况
在标记后面似乎还隐藏着额外的实验性优化(-XX:+AggressiveUnboxing
,部分-XX:+AggressiveOpts
)。据我所知,他们可能会破坏Integer.valueOf(int)
的身份保证,因此不完全符合规范
一个切线:实验/研究甚至更进一步,它可以将分配推迟到那些对象确实逃逸的代码路径,而当它们没有逃逸时,却将它们留在堆栈上进行标量分解。这还不是常规vm的一部分,主要由JRuby和Nashorn等JVM上运行的非java语言使用
由于所有这些都是运行时优化,因此无法保证会发生这种情况。因此,您必须使用诊断标志来测量效果或跟踪编译器的决策
我之所以不认为它们会像其他类一样执行堆分配,是因为可选类等都是“基于值的类”
我认为目前这些属性仅仅是为了确保对象是不可变的和线程安全的。我不知道EA之外的任何优化是否利用了互换性特性
我怀疑规范语言主要是为了在它们最终作为Java的一部分进入Java时提供对它们的前向兼容性
遵循这些规则也使转义分析/堆栈分配更容易。它们是对象,行为与任何其他对象一样。这取决于您在做什么。为什么不在有和没有可选的测试用例的情况下对用例进行基准测试?我很确定这不会成为你代码的瓶颈…请看我的编辑。可选类型是基于值的类,这似乎意味着它们的分配方式不同,或者可以利用某些优化。@w.brian:感谢您对此进行扩展。查看我的更新。