2017-11-10 140 views
1

假设我有一个值类型Foo,并且方法Bar接受对Foo的引用。大多数语言都允许我在堆栈上分配一个新的Foo,并且当我尝试将它传递给Bar时,它会自动将其装箱。但是,据我所知,这涉及将Foo值复制到堆上,然后使用该引用。垃圾收集语言是否可以在堆栈上分配内联对象?

语言是否有可能在堆栈中包含分配垃圾收集对象的方法?当方法结束时,运行时可以检查对象是否仍在使用,只有这样它才需要在堆上分配对象,并更新引用。

我想这会提高不保留引用的方法的性能,并且会妨碍方法的性能。

+1

阅读有关[Escape Analysis](https://en.m.wikipedia.org/wiki/Escape_analysis)在Java中使用的示例。 –

+0

请参阅https://stackoverflow.com/questions/25903320/creating-objects-on-the-stack-memory-in-java – Raedwald

回答

1

是的,格拉尔的partial escape analysis这样做。虽然常规EA只能在对象不能转义的情况下进行堆栈分配(更精确地说:分解为字段,将字段放入堆栈中)。EA可以在堆栈上乐观地分配数据,并且只在不常见的情况下将数据转换为对象必须存在。

另请注意,垃圾收集不是二元选择。您可以将环境混合搭配垃圾收集,重新计数,竞技场或基于范围的分配器,并自动释放和完全手动管理。在这种情况下,堆栈分配也可能是后一种情况,而一些堆将被垃圾收集。

+0

可能值得注意的是,TLAB分配的工作效率与堆栈分配一样有效,只需要一个指针碰到最好的情况,虽然已经比OP描述的更好,因为将'Foo'传递给方法不需要复制对象,事实上,即使将对象的引用存储到堆变量中也不需要这种复制。只有当物体存在下一个gc时,它才会被复制。在EA之后分解成字段的工作甚至更好,因为它启用了后续优化,将这些字段视为局部变量。 – Holger