簡體   English   中英

在方法調用期間創建的本地Java對象的生命周期

[英]Life cycle of local Java objects created during a method call

在方法調用中,如果我在該調用期間創建了一個對象。 這些對象何時被垃圾收集?

它們是否放在堆上,然后將垃圾與堆上的其他對象一起收集。 或者他們之前是垃圾收集,因為他們不需要。 該方法的執行已完成。

方法范圍內創建的對象在方法關閉時有資格進行垃圾回收 - 除非該引用作為返回值傳回。 在這種情況下,調用者可能會或可能不會掛在該引用上並阻止它被gc'd。

由於垃圾收集器根據自己的燈光在自己的線程上運行,因此您不一定知道何時清理對象,或者其他地方分配的對象是否也符合條件。

這不是那么容易 - 最后,每個對象都是以某種方法創建的。

VM /編譯器需要進行轉義路徑分析,以檢測此對象的引用是否可以以某種方式轉義 - 想象一下調用newObject.toString()。 你和我知道(希望)這不會造成傷害,並且仍然沒有引用該對象,因為它不會將自身鏈接到全局變量。 但虛擬機沒有。

雖然現代VM將進行此類分析並處理垃圾收集中特殊的真實短期對象,但從“高級”角度來看,它們只是對象。 其他一切都是復雜的低級優化。

無論如何,正如duffymo所說 - 當這些物體被釋放時,這是不確定的。

方法的執行已經結束並且現在對象超出范圍的事實是無關緊要的。
垃圾收集是運行時系統的隱式操作,它在與您的代碼並行的單獨線程中運行,實現特定的垃圾收集算法。
垃圾收集線程在不可預測的時間運行 - 但很多時候,根據java文檔大約每秒鍾一次,當內存幾乎耗盡時,評估哪些對象有資格被垃圾收集,即根指針沒有引用它們,例如靜態變量。
因此,根指針可訪問的每個對象都被標記,然后遞歸地標記這些對象引用的對象等。
這可能意味着掃描整個過程空間。 完成后,所有未從之前掃描中“標記”的對象都會轉到空閑列表(GC'd)。
你可以看到這是一個繁重的操作。

該方法的執行已完成。

因此,事實上你已經超出了你所調用的方法的范圍,因為它已經完成,這是無關緊要的。 這並不意味着運行時知道該對象已完成(因為GC並行運行)。
它不像在C ++中那樣,在方法的最后,程序員會在對象上調用delete,因為它不需要。 在Java中,在方法結束時不會自動調用“delete”。
GC線程最終將意識到該方法和CG不再引用堆上分配的對象。
如果您願意,您可以隨時致電GC:

System.gc();

但無論如何,GC遲早會運行。
需要注意的一點是,只要根指針對方法的引用就不能是GC的。
因此,如果在您的方法中,您通過堆上的new對象創建並將引用存儲在靜態容器中或將其返回給調用者,則該對象比該方法更長。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM