物件引用是怎樣嚴重影響垃圾收集器的
物件引用是怎樣嚴重影響垃圾收集器的[@more@] 果您認為 Java 遊戲開發人員是 Java 程式設計世界的一級方程式賽車手,那麼您就會明白為什麼他們會如此地重視程式的效能。 遊戲開發人員幾乎每天都要面對的效能問題,往往超過了一般程式設計師考慮問題的範圍。哪裡可以找到這些特殊的開發人員呢?Java 遊戲社群就是一個好去處(參見 參考資料)。 雖然在這個站點可能沒有很多關於伺服器端的應用,但是我們依然可以從中受益,看看這些“惜位元如金”的遊戲開發人員每天所面對的,我們往往能從中得到寶貴的經驗。讓我們開始遊戲吧!
物件洩漏
遊戲程式設計師跟其他程式設計師一樣――他們也需要理解 Java 執行時環境的一些微妙之處,比如垃圾收集。垃圾收集可能是使您感到難於理解的較難的概念之一, 因為它並不能總是毫無遺漏地解決 Java 執行時環境中堆管理的問題。似乎有很多類似這樣的討論,它的開頭或結尾寫著:“我的問題是關於垃圾收集”。
假如您正面遭遇記憶體耗盡(out-of-memory)的錯誤。於是您使用檢測工具想要找到問題所在,但這是徒勞的。您很容易想到另外一個比較可信的原因:這是 Java 虛擬機器堆管理的問題,而不會認為這是您自己的程式的緣故。但是,正如 Java 遊戲社群的資深專家不止一次地解釋的,Java 虛擬機器並不存在任何被證實的物件洩漏問題。實踐證明,垃圾收集器一般能夠精確地判斷哪些物件可被收集,並且重新收回它們的記憶體空間給 Java 虛擬機器。所以,如果您遇到了記憶體耗盡的錯誤,那麼這完全可能是由您的程式造成的,也就是說您的程式中存在著“無意識的物件保留(unintentional object retention)”。
記憶體洩漏與無意識的物件保留
記憶體洩漏和無意識的物件保留的區別是什麼呢?對於用 Java 語言編寫的程式來說,確實沒有區別。兩者都是指在您的程式中存在一些物件引用,但實際上您並不需要引用這些物件。一個典型的例子是向一個集合中加入一些物件以便以後使用它們,但是您卻忘了在使用完以後從集合中刪除這些物件。因為集合可以無限制地擴大,並且從來不會變小,所以當您在集合中加入了太多的物件(或者是有很多的物件被集合中的元素所引用)時,您就會因為堆的空間被填滿而導致記憶體耗盡的錯誤。垃圾收集器不能收集這些您認為已經用完的物件,因為對於垃圾收集器來說,應用程式仍然可以透過這個集合在任何時候訪問這些物件,所以這些物件是不可能被當作垃圾的。
對於沒有垃圾收集的語言來說,例如 C++ ,記憶體洩漏和無意識的物件保留是有區別的。C++ 程式跟 Java 程式一樣,可能產生無意識的物件保留。但是 C++ 程式中存在真正的記憶體洩漏,即應用程式無法訪問一些物件以至於被這些物件使用的記憶體無法釋放且返還給系統。令人欣慰的是,在 Java 程式中,這種記憶體洩漏是不可能出現的。所以,我們更喜歡用“無意識的物件保留”來表示這個令 Java 程式設計師抓破頭皮的記憶體問題。這樣,我們就能區別於其他使用沒有垃圾收集語言的程式設計師。
跟蹤被保留的物件
那麼當發現了無意識的物件保留該怎麼辦呢?首先,需要確定哪些物件是被無意保留的,並且需要找到究竟是哪些物件在引用它們。然後必須安排好 應該在哪裡釋放它們。最容易的方法是使用能夠對堆產生快照的檢測工具來標識這些物件,比較堆的快照中物件的數目,跟蹤這些物件,找到引用這些物件的物件,然後強制進行垃圾收集。有了這樣一個檢測器,接下來的工作相對而言就比較簡單了:
等待直到系統達到一個穩定的狀態,這個狀態下大多數新產生的物件都是暫時的,符合被收集的條件;這種狀態一般在程式所有的初始化工作都完成了之後。
強制進行一次垃圾收集,並且對此時的堆做一份物件快照。
進行任何可以產生無意地保留的物件的操作。
再強制進行一次垃圾收集,然後對系統堆中的物件做第二次物件快照。
比較兩次快照,看看哪些物件的被引用數量比第一次快照時增加了。因為您在快照之前強制進行了垃圾收集,那麼剩下的物件都應該是被應用程式所引用的物件,並且透過比較兩次快照我們可以準確地找出那些被程式保留的、新產生的物件。
根據您對應用程式本身的理解,並且根據對兩次快照的比較,判斷出哪些物件是被無意保留的。
跟蹤這些物件的引用鏈,找出究竟是哪些物件在引用這些無意地保留的物件,直到您找到了那個根物件,它就是產生問題的根源。
物件洩漏
遊戲程式設計師跟其他程式設計師一樣――他們也需要理解 Java 執行時環境的一些微妙之處,比如垃圾收集。垃圾收集可能是使您感到難於理解的較難的概念之一, 因為它並不能總是毫無遺漏地解決 Java 執行時環境中堆管理的問題。似乎有很多類似這樣的討論,它的開頭或結尾寫著:“我的問題是關於垃圾收集”。
假如您正面遭遇記憶體耗盡(out-of-memory)的錯誤。於是您使用檢測工具想要找到問題所在,但這是徒勞的。您很容易想到另外一個比較可信的原因:這是 Java 虛擬機器堆管理的問題,而不會認為這是您自己的程式的緣故。但是,正如 Java 遊戲社群的資深專家不止一次地解釋的,Java 虛擬機器並不存在任何被證實的物件洩漏問題。實踐證明,垃圾收集器一般能夠精確地判斷哪些物件可被收集,並且重新收回它們的記憶體空間給 Java 虛擬機器。所以,如果您遇到了記憶體耗盡的錯誤,那麼這完全可能是由您的程式造成的,也就是說您的程式中存在著“無意識的物件保留(unintentional object retention)”。
記憶體洩漏與無意識的物件保留
記憶體洩漏和無意識的物件保留的區別是什麼呢?對於用 Java 語言編寫的程式來說,確實沒有區別。兩者都是指在您的程式中存在一些物件引用,但實際上您並不需要引用這些物件。一個典型的例子是向一個集合中加入一些物件以便以後使用它們,但是您卻忘了在使用完以後從集合中刪除這些物件。因為集合可以無限制地擴大,並且從來不會變小,所以當您在集合中加入了太多的物件(或者是有很多的物件被集合中的元素所引用)時,您就會因為堆的空間被填滿而導致記憶體耗盡的錯誤。垃圾收集器不能收集這些您認為已經用完的物件,因為對於垃圾收集器來說,應用程式仍然可以透過這個集合在任何時候訪問這些物件,所以這些物件是不可能被當作垃圾的。
對於沒有垃圾收集的語言來說,例如 C++ ,記憶體洩漏和無意識的物件保留是有區別的。C++ 程式跟 Java 程式一樣,可能產生無意識的物件保留。但是 C++ 程式中存在真正的記憶體洩漏,即應用程式無法訪問一些物件以至於被這些物件使用的記憶體無法釋放且返還給系統。令人欣慰的是,在 Java 程式中,這種記憶體洩漏是不可能出現的。所以,我們更喜歡用“無意識的物件保留”來表示這個令 Java 程式設計師抓破頭皮的記憶體問題。這樣,我們就能區別於其他使用沒有垃圾收集語言的程式設計師。
跟蹤被保留的物件
那麼當發現了無意識的物件保留該怎麼辦呢?首先,需要確定哪些物件是被無意保留的,並且需要找到究竟是哪些物件在引用它們。然後必須安排好 應該在哪裡釋放它們。最容易的方法是使用能夠對堆產生快照的檢測工具來標識這些物件,比較堆的快照中物件的數目,跟蹤這些物件,找到引用這些物件的物件,然後強制進行垃圾收集。有了這樣一個檢測器,接下來的工作相對而言就比較簡單了:
等待直到系統達到一個穩定的狀態,這個狀態下大多數新產生的物件都是暫時的,符合被收集的條件;這種狀態一般在程式所有的初始化工作都完成了之後。
強制進行一次垃圾收集,並且對此時的堆做一份物件快照。
進行任何可以產生無意地保留的物件的操作。
再強制進行一次垃圾收集,然後對系統堆中的物件做第二次物件快照。
比較兩次快照,看看哪些物件的被引用數量比第一次快照時增加了。因為您在快照之前強制進行了垃圾收集,那麼剩下的物件都應該是被應用程式所引用的物件,並且透過比較兩次快照我們可以準確地找出那些被程式保留的、新產生的物件。
根據您對應用程式本身的理解,並且根據對兩次快照的比較,判斷出哪些物件是被無意保留的。
跟蹤這些物件的引用鏈,找出究竟是哪些物件在引用這些無意地保留的物件,直到您找到了那個根物件,它就是產生問題的根源。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10901326/viewspace-965631/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何防止勒索軟體攻擊造成嚴重影響
- 為什麼業務知識會嚴重影響建模效果?
- Linux穩定版核心撤回嚴重影響效能的Spectre補丁Linux
- 網站顏色嚴重影響消費者購買決定網站
- 廣告行業抱怨 Safari 的防追蹤技術 ITP 太有效,嚴重影響收入行業
- 報告稱網站顏色嚴重影響消費者購買決定網站
- JVM垃圾收集器(八)JVM
- 垃圾收集器學習
- 政府網站和政務新媒體內容存在問題,會造成哪些嚴重影響?網站
- JVM垃圾收集器總結JVM
- JVM垃圾收集器專題JVM
- JVM 經典垃圾收集器JVM
- java幾種垃圾收集方法和垃圾收集器Java
- 垃圾收集器與記憶體分配策略_hotspot垃圾收集演算法實現和垃圾收集器記憶體HotSpot演算法
- Premiere影片重影效果怎麼做?Premiere製作影片重影效果的方法REM
- HotSpot的7種垃圾收集器組合HotSpot
- java中各種垃圾收集器的原理Java
- GC 分代回收 - 垃圾收集器GC
- Java G1 垃圾收集器Java
- JVM(五)-垃圾收集器入門JVM
- JDK1.6中垃圾收集器JDK
- JVM G1垃圾收集器JVM
- Java虛擬機器學習 - 垃圾收集器Java虛擬機機器學習
- Java新的Z垃圾收集器ZGC介紹JavaGC
- java8預設使用的垃圾收集器Java
- 深入理解 JVM 之 垃圾收集器JVM
- JVM調優:HotSpot JVM垃圾收集器JVMHotSpot
- 10. 系統分析垃圾收集器
- 垃圾收集器與Java程式設計Java程式設計
- Premiere視訊重影效果怎麼做?Premiere製作視訊重影效果的方法REM
- PHP垃圾收集器和程式設計師的幽默PHP程式設計師
- 美團二季度營收247億元,到店、酒店等業務下滑13.4%,將繼續受疫情嚴重影響營收
- 恰到好處的香港伺服器租用是怎麼樣的伺服器
- JVM虛擬機器-垃圾回收機制與垃圾收集器概述JVM虛擬機
- 垃圾收集器與記憶體分配策略_垃圾收集演算法記憶體演算法
- 深入理解JVM,7種垃圾收集器JVM
- Java虛擬機器04——垃圾收集器Java虛擬機
- 垃圾收集器與記憶體分配策略記憶體