国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

用軟引用阻止內存泄漏

2019-11-18 12:13:16
字體:
來源:轉載
供稿:網友

    在 java 理論和實踐 的 前一期文章 中,Java? 清潔工程師 Brian Goetz 探究了弱引用(weak references),它讓您警告垃圾收集器,您想要維護一個對象的引用,而不會阻止該對象被垃圾收集。在本期文章中,他將解釋 Reference 對象的另外一種形式,即軟引用(soft references),用于幫助垃圾收集器治理內存使用和消除潛在的內存泄漏。 

  垃圾收集可以使 Java 程序不會出現內存泄漏,至少對于比較狹窄的 “內存泄漏” 定義來說如此,但是這并不意味著我們可以完全忽略 Java 程序中的對象生存期(lifetime)問題。當我們沒有對對象生命周期(lifecycle)引起足夠的重視或者破壞了治理對象生命周期的標準機制時,Java 程序中通常就會出現內存泄漏。例如,上一次 我們看到了,不能劃分對象的生命周期會導致,在試圖將元數據關聯到瞬時對象時出現意外的對象保持。還有一些其他的情況可以類似地忽略或破壞對象生命周期治理,并導致內存泄漏。

  對象游離

  一種形式的內存泄漏有時候叫做對象游離(object loitering),是通過清單 1 中的 LeakyChecksum 類來說明的,清單 1 中有一個 getFileChecksum() 方法用于計算文件內容的校驗和。getFileChecksum() 方法將文件內容讀取到緩沖區中以計算校驗和。一種更加直觀的實現簡單地將緩沖區作為 getFileChecksum() 中的本地變量分配,但是該版本比那樣的版本更加 “聰明”,不是將緩沖區緩存在實例字段中以減少內存 churn。該 “優化”通常不帶來預期的好處;對象分配比很多人期望的更便宜。(還要注重,將緩沖區從本地變量提升到實例變量,使得類若不帶有附加的同步,就不再是線程安全的了。直觀的實現不需要將 getFileChecksum() 聲明為 synchronized,并且會在同時調用時提供更好的可伸縮性。)


  清單 1. 展示 “對象游離” 的類

// BAD CODE - DO NOT EMULATEpublic class LeakyChecksum {    PRivate byte[] byteArray;        public synchronized int getFileChecksum(String fileName) {        int len = getFileSize(fileName);        if (byteArray == null  byteArray.length < len)            byteArray = new byte[len];        readFileContents(fileName, byteArray);        // calculate checksum and return it    }}

  這個類存在很多的問題,但是我們著重來看內存泄漏。緩存緩沖區的決定很可能是根據這樣的假設得出的,即該類將在一個程序中被調用許多次,因此它應該更加有效,以重用緩沖區而不是重新分配它。但是結果是,緩沖區永遠不會被釋放,因為它對程序來說總是可及的(除非 LeakyChecksum 對象被垃圾收集了)。更壞的是,它可以增長,卻不可以縮小,所以 LeakyChecksum 將永久保持一個與所處理的最大文件一樣大小的緩沖區。退一萬步說,這也會給垃圾收集器帶來壓力,并且要求更頻繁的收集;為計算未來的校驗和而保持一個大型緩沖區并不是可用內存的最有效利用。

  LeakyChecksum 中問題的原因是,緩沖區對于 getFileChecksum() 操作來說邏輯上是本地的,但是它的生命周期已經被人為延長了,因為將它提升到了實例字段。因此,該類必須自己治理緩沖區的生命周期,而不是讓 JVM 來治理。


  軟引用

  在 前一期文章 中我們看到了,弱引用如何可以給應用程序提供當對象被程序使用時另一種到達該對象的方法,但是不會延長對象的生命周期。Reference 的另一個子類 —— 軟引用 —— 可滿足一個不同卻相關的目的。其中弱引用答應應用程序創建不妨礙垃圾收集的引用,軟引用答應應用程序通過將一些對象指定為 “eXPendable” 而利用垃圾收集器的幫助。盡管垃圾收集器在找出哪些內存在由應用程序使用哪些沒在使用方面做得很好,但是確定可用內存的最適當使用還是取決于應用程序。假如應用程序做出了不好的決定,使得對象被保持,那么性能會受到影響,因為垃圾收集器必須更加辛勤地工作,以防止應用程序消耗掉所有內存。

  高速緩存是一種常見的性能優化,答應應用程序重用以前的計算結果,而不是重新進行計算。高速緩存是 CPU 利用和內存使用之間的一種折衷,這種折衷理想的平衡狀態取決于有多少內存可用。若高速緩存太少,則所要求的性能優勢無法達到;若太多,則性能會受到影響,因為太多的內存被用于高速緩存上,導致其他用途沒有足夠的可用內存。因為垃圾收集器比應用程序更適合決定內存需求,所以應該利用垃圾收集器在做這些決定方面的幫助,這就是件引用所要做的。

  假如一個對象惟一剩下的引用是弱引用或軟引用,那么該對象是軟可及的(softly reachable)。垃圾收集器并不像其收集弱可及的對象一樣盡量地收集軟可及的對象,相反,它只在真正 “需要” 內存時才收集軟可及的對象。軟引用對于垃圾收集器來說是這樣一種方式,即 “只要內存不太緊張,我就會保留該對象。但是假如內存變得真正緊張了,我就會去收集并處理這個對象。” 垃圾收集器在可以拋出 OutOfMemoryError 之前需要清除所有的軟引用。



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 和龙市| 广宗县| 吴桥县| 浦江县| 慈溪市| 丰城市| 聊城市| 吉林省| 肇东市| 汶川县| 江城| 平泉县| 武冈市| 崇文区| 巩留县| 汾阳市| 三河市| 汾西县| 穆棱市| 原平市| 城固县| 乌兰察布市| 兖州市| 岑溪市| 建昌县| 吴江市| 内黄县| 祁门县| 始兴县| 昌平区| 清河县| 库车县| 桐乡市| 云南省| 同德县| 眉山市| 宾川县| 海城市| 翁牛特旗| 德清县| 北安市|