1. 程式人生 > >java弱型別總結(轉)

java弱型別總結(轉)

(因為最近寫個小工具,在手機平臺上需要用到,所以整理了大部分相關文件,希望對讀者有用,若有筆誤請來信告訴謝謝:[email protected]

1.Java垃圾回收器概述

  Java2平臺裡面引入了java.lang.ref包,這個包中的類可以讓我們引用物件,而是的這些物件不用停留在記憶體中。不僅僅如此,這些類和Java本身的垃圾回收器還存在一定的互動。我們平時開發的時候有時候會用到System.gc()方法,而Java裡面GC的基本工作原理又是如何呢?當然使用Java引用類主要目的是為了和Java垃圾回收器進行有限的互動,從而全面提升記憶體的管理效率,這種情況在嵌入式系統和實時系統以及一些對記憶體要求嚴格的系統裡面比較湊效。

1)GC的基本原理

  Java的記憶體管理主要指的是對記憶體中的物件的管理,包括針對這些物件進行記憶體的分配和釋放等各種操作,學過Java的人都瞭解Java本身的記憶體模型,對於一個Java的物件而言,儲存主要分為兩種,一種是記憶體堆(Heap),記憶體堆是無序的,主要用來存放建立的Java物件;一種是記憶體棧(Stack),主要用來存放Java引用,然後在管理過程使用Java引用指向Java物件。而GC就是負責在物件“不可達”的時候將物件回收,常見的語句例如:

Object o = null;

  而CG本身是如何工作的呢?當系統在建立物件的時候,即當我們使用new關鍵字建立一個物件的時候,GC就開始監控物件的地址、大小以及使用狀態。一般情況下,Java的GC機制都有特定的回收演算法,GC通常會使用有向圖的方式來記錄隊中的所有物件,通過此種方式確定哪些物件是“可達的”,而哪些是“不可達的”。當GC判斷一些物件不可達的時候,GC就有責任回收相關記憶體空間。但是,因為平臺的不同,往往在呼叫System.gc()的時候,存在太多不確定性,可以這樣認為,當程式呼叫了System.gc()過後,僅僅是程式向JVM傳送了請求,至於JVM究竟在什麼時候進行垃圾回收,不同的平臺不一樣。(*:需要解決的誤區是不要覺得System.gc()呼叫了過後,垃圾回收器一定會對系統記憶體進行回收,系統回收相關記憶體取決於平臺和系統。)

2)增量方式GC(IncrementalGC)

  GC在JVM中通常是啟動了一個新的程序或者一組新的程序,它本身和Java使用者程式一樣需要佔用heap空間,執行時也佔用CPU。設計GC的時候,必須要在停頓時間和回收率之間進行權衡,原因在於它本身佔用了Heap,如果GC執行時間太長,使用者就會感覺到Java程式本身會有一定的停頓,如果執行時間太短,則有很多記憶體沒有回收,使得程式裡面建立的Java物件佔用了大量的記憶體。增量方式的GC就是通過一定的回收演算法,把一個長時間的中斷,分成很多小的中斷,通過這種方式減少GC對程式本身的影響。其實增量方式整體效能比不上普通的高,但是能夠減少停頓時間,改善使用者的使用者體驗。當然除了這樣的方式,GC整體的方式為:

  引用計數法(Reference Counting Collector) ;

  Tracing演算法(Tracing Collector);

  Compacting演算法(Compacting Collector) ;

  Copying演算法(Coping Collector) ;

  Generation演算法(Generational Collector) ;

  Adaptive演算法(Adaptive Collector) ;

  至於相關的演算法可以去查閱相關的文件

2.Java中的物件引用分類

  Java中的物件引用主要有以下幾種型別:

  1)強可及物件(strongly reachable):

可以通過強引用訪問的物件,一般來說,我們平時寫程式碼的方式都是使用的強引用物件,比如下邊的程式碼段:

  StringBuilder builder= new StringBuilder();

  上邊程式碼部分引用obj這個引用將引用記憶體堆中的一個物件,這種情況下,只要obj的引用存在,垃圾回收器就永遠不會釋放該物件的儲存空間。這種物件我們又成為強引用(Strong references),這種強引用方式就是Java語言的原生的Java引用,我們幾乎每天程式設計的時候都用到。上邊程式碼JVM儲存了一個StringBuilder型別的物件的強引用在變數builder呢。強引用和GC的互動是這樣的,如果一個物件通過強引用可達或者通過強引用鏈可達的話這種物件就成為強可及物件,這種情況下的物件垃圾回收器不予理睬。如果我們開發過程不需要垃圾回器回收該物件,就直接將該物件賦為前引用。

  2)軟可及物件(softly reachable):

  不通過強引用訪問的物件,即不是強可及物件,但是可以通過軟引用訪問的物件就成為軟可及物件,軟可及物件就需要使用類SoftReference(java.lang.ref.SoftReference)。此種類型的引用主要用於記憶體比較敏感的快取記憶體,而且此種引用還是具有較強的引用功能,當記憶體不夠的時候GC會回收這類記憶體,因此如果記憶體充足的時候,這種引用通常不會被回收的。不僅僅如此,這種引用物件在JVM裡面保證在丟擲OutOfMemory異常之前,設定成為null。通俗地講,這種型別的引用保證在JVM記憶體不足的時候全部被清楚,但是有個關鍵在於:垃圾收集器在執行時是否釋放軟可及物件是不確定的,而且使用垃圾回收演算法並不能保證一次性尋找到所有的軟可及物件。當垃圾回收器每次執行的時候都可以隨意釋放不是強可及物件佔用的記憶體,如果垃圾回收器找到了軟可及物件過後,可能會進行以下操作:

【1】將SoftReference物件的referent域設定成為null,從而使該物件不再引用heap物件。

【2】SoftReference引用過的記憶體堆上的物件一律被生命為finalizable。

【3】當記憶體堆上的物件finalize()方法被執行而且該物件佔用的記憶體被釋放,SoftReference物件就會被新增到它的ReferenceQueue,前提條件是ReferenceQueue本身是存在的。

  既然Java裡面存在這樣的物件,那麼我們在編寫程式碼的時候如何建立這樣的物件呢?建立步驟如下:

  先建立一個物件,並使用普通引用方式【強引用】,然後再建立一個SoftReference來引用該物件,最後將普通引用設定為null,通過這樣的方式,這個物件就僅僅保留了一個SoftReference引用,同時這種情況我們所建立的物件就是SoftReference物件。一般情況下,我們可以使用該引用來完成Cache功能,就是前邊說的用於快取記憶體,保證最大限度使用記憶體而不會引起記憶體洩漏的情況。下邊的程式碼段:

public static void main(String args[])

{

  //建立一個強可及物件

  A a = new A();

  //建立這個物件的軟引用SoftReference

SoftReference sr = new SoftReference(a);

  //將強引用設定為空,以遍垃圾回收器回收強引用

a = null;

  //下次使用該物件的操作

if( sr != null ){

    a = (A)sr.get();

  }else{

    //這種情況就是由於記憶體過低,已經將軟引用釋放了,因此需要重新裝載一次

    a = new A();

    sr = new SoftReference(a);

  }

}

  軟引用技術使得Java系統可以更好地管理記憶體,保持系統穩定,防止記憶體洩漏,避免系統崩潰,因此在處理一些記憶體佔用大而且生命週期長使用不頻繁的物件可以使用該技術。

  3)弱可及物件(weakly reachable):

  不是強可及物件同樣也不是軟可及物件,僅僅通過弱引用WeakReference(java.lang.ref.WeakReference)訪問的物件,這種物件的用途在於規範化對映(canonicalized mapping),對於生存週期相對比較長而且重新建立的時候開銷少的物件,弱引用也比較有用,和軟引用物件不同的是,垃圾回收器如果碰到了弱可及物件,將釋放WeakReference物件的記憶體,但是垃圾回收器需要執行很多次才能夠找到弱可及物件。弱引用物件在使用的時候,可以配合ReferenceQueue類使用,如果弱引用被回收,JVM就會把這個弱引用加入到相關的引用佇列中去。最簡單的弱引用方法如以下程式碼:

  WeakReference weakWidget = newWeakReference(classA);

  在上邊程式碼裡面,當我們使用weakWidget.get()來獲取classA的時候,由於弱引用本身是無法阻止垃圾回收的,所以我們也許會拿到一個null返回。【*:這裡提供一個小技巧,如果我們希望取得某個物件的資訊,但是又不影響該物件的垃圾回收過程,我們就可以使用WeakReference來記住該物件,一般我們在開發偵錯程式和優化器的時候使用這個是很好的一個手段。】

  如果上邊的程式碼部分,我們通過weakWidget.get()返回的是null就證明該物件已經被垃圾回收器回收了,而這種情況下弱引用物件就失去了使用價值,GC就會定義為需要進行清除工作。這種情況下弱引用無法引用任何物件,所以在JVM裡面就成為了一個死引用,這就是為什麼我們有時候需要通過ReferenceQueue類來配合使用的原因,使用了

相關推薦

java型別總結

(因為最近寫個小工具,在手機平臺上需要用到,所以整理了大部分相關文件,希望對讀者有用,若有筆誤請來信告訴謝謝:[email protected])1.Java垃圾回收器概述  Java2平臺裡

Java IO流學習總結

rar output 出現 arr system 不存在 技術分享 輸出 寫入 原文地址:http://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html Java流操作有關的類或接口: Java流類圖結構:

Java基礎學習總結122——Java八種基本資料型別的包裝類及其裝箱拆箱詳解

一、基本資料型別及對應的包裝類基本資料型別對應的包裝類byteByteshortShortintIntegerlongLongcharCharacterfloatFloatdoubleDoublebooleanBoolean每個包裝類的物件可以封裝一個相應的基本型別的資料,並提供了其它一些有用的方法。包裝類物

java enum(列舉)使用詳解和總結

enum 的全稱為 enumeration, 是 JDK 1.5  中引入的新特性,存放在 java.lang 包中。     下面是我在使用 enum 過程中的一些經驗和總結,主要包括如下內容: 1. 原始的介面定義常量 2. 語法(定義) 3. 遍歷、switch 等常用

Java之怎麼通過java去呼叫並執行shell指令碼以及問題總結

背景 我們在開發過程中,大部分是java開發, 而在文字處理過程中,主要就是指令碼進行開發。 java開發的特點就是我們可以很早地進行TDDL, METAQ 等等地對接; 而指令碼開發的特點就是在進行批處理的時候非常方便。 前陣子我遇到這麼一個需求場景: 對抓

Java集合及concurrent併發包總結

    集合包最常用的有Collection和Map兩個介面的實現類,Colleciton用於存放多個單物件,Map用於存放Key-Value形式的鍵值對。  Collection中最常用的又分為兩種型別的介面:List和Set,兩者最明顯的差別為List支援放入重複的元素,而Set不支援。List最常用的實

最詳細的 Android Toolbar 開發實踐總結

activity resource listener nba flat xmlns mat https ons 轉自:http://www.codeceo.com/article/android-toolbar-develop.html 過年前發了一篇介紹 Transluc

C++中的static關鍵字的總結

blank protected .com 如果 發現 內部實現 屬於 out 服務  C++的static有兩種用法:面向過程程序設計中的static和面向對象程序設計中的static。前者應用於普通變量和函數,不涉及類;後者主要說明static在類中的作用。 1.面向過程

erlang程序優化點的總結

數據庫 機器 ria 嚴重 多線程 分別是 簡單 構造 代碼實現 註意,這裏只是給出一個總結,具體性能需要根據實際環境和需要來確定 霸爺指出,新的erlang虛擬機有很多調優啟動參數,今後現在這個方面深挖一下。 1. 進程標誌設置: 消息和binary內

Java IO學習總結

file flush writer directory 創建 str java 資源 tab 一、File 類 Java中不管文件還是目錄都可以使用File類操作,File能新建、刪除、重命名文件和目錄,但是不能訪問文件內容本身,訪問文件內容需要使用輸入輸出流。 Fi

Java Script學習 4

rom 瀏覽器 html 表單 有助於 執行 script5 可能 一個 字面量 JavaScript 嚴格模式(use strict) JavaScript 嚴格模式(strict mode)即在嚴格的條件下運行。 使用 "use strict" 指令 "use stri

C#中WinForm程序退出方法技巧總結

ren sender body 登錄 ble 按鈕 動作 打開 alt 一、關閉窗體 在c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();Application.ExitThread(); System.E

常見性能優化策略的總結

觸發 air 技術 敏捷 返回 好的 依賴 pan 支付 看到一篇好文,轉過來好好學習 閱讀目錄 代碼 數據庫 緩存 異步 NoSQL JVM調優 多線程與分布式 度量系統(監控、報警、服務依賴管理) 案例一:商家與控制區關系的刷新job 案例二:POI緩存設計與實現

<正則吃餃子> :關於Java的native方法

any 所有 接口 當我 article 正是 str 直接 空間 感謝作者的分享,原文地址:http://blog.csdn.net/wike163/article/details/6635321 一. 什麽是Native Method 簡單地講,一個Native

前端筆記----jquery入門知識點總結

outer 尺寸 對象 層級 ani 入門 fontsize fun click http://www.cnblogs.com/cwp-bg/p/7633623.html 一、jquery的加載方法 $(document).ready(function(){js代碼});

Java Web學習總結7JSP

sco runt util 註意細節 服務 private tin 多行 cnblogs 一,JSP基礎語法 1,JSP模板元素 JSP頁面中的HTML內容稱之為JSP模版元素。 JSP模版元素定義了網頁的基本骨架,即定義了頁面的結構和外觀。 2,JSP腳本

Java Web學習總結12Filter過濾器

strong xsd filter過濾器 應用程序 map .com pre one exception 一,Filter簡介 Filter也稱之為過濾器,Filter是對客戶端訪問資源的過濾,符合條件放行,不符合條件不放行,並且可以對目標資源訪問前後進行邏輯處理。

安卓手機GPU OpenCL總結

性能 網上 gin bsp 策略 測試的 公司 ocl adding 前段時間,把市面上手機GPU OpenCL支持情況做了一個總結。總結如下: 目前,手機 GPU 市面有四個公司產品:Qualcomm, Imagination Technologies,ARM, Viva

Linux命令總結

查看登陸 oca 下一個 同時 找到 刪除用戶 mtime 高亮 數值 1.ls [選項] [目錄名 | 列出相關目錄下的所有目錄和文件 -a 列出包括.a開頭的隱藏文件的所有文件 -A 通-a,但不列出"."和".." -l 列出文件的詳細信息 -c 根據ctim

Java獲取指定時間

throws 一個 lda sta ref github system time pty 說明:從LocalDate的API上看,主要用於快速獲取當前年月日,而DateFormatter也基本上伴隨著使用。如果是操作Date對象的,主要是用於時間戳等,伴隨著使用的是Simp