2017-11-10 182 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