1. 程式人生 > >java物件之間相互迴圈引用例項

java物件之間相互迴圈引用例項

在C++中使用過智慧指標的同學們應該都清楚智慧指標對C++中記憶體管理帶來的極大便利,但是也會引入一些頭疼的問題,比如智慧指標帶來的迴圈引用的問題,這個問題在之前的專案中一直沒有很好的解決

        最近參與到android的專案開發,對java的記憶體的管理有了一個初步的瞭解,很容易想到了迴圈引用的問題。比如下面這個例子:

        public void buidDog()

        {

           Dog newDog = new Dog();

          Tail newTail = new Tail();

          newDog.tail = newTail;

         newTail.dog = newDog;

        }

        在這裡,newTail中拿著對newDog的引用,newDog中拿著對newTail的引用。如果newDog要被回收,前提是newTail被先回收,這樣才能釋放對newDog的引用。但是反回過來,newTail要被回收的前提是newDog要被先回收。當buildDog函式退出後,看起來垃圾回收管理似乎就始終無法回收這兩個實際已經不再需要的物件。

         垃圾回收機制究竟能否解決迴圈引用這一困境,帶著這個疑問找了一些資料,找到了一個比較滿意的解釋。在《Java Platform Performance: Strategies and Tactics》這本書的附錄A中有一處說明,這本書出自sun公司java團隊員工,應該算比較權威的。其中有這樣一段(

http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997428):

“It's important to note that not just any strong reference will hold an object in memory. These must be references that chain from a garbage collection root. GC roots are a special class of variable that includes

Temporary variables on the stack (of any thread)

Static variables (from any class)

Special references from JNI native code”。

這段話可以簡單的理解就是強引用並不能保證物件不被回收。垃圾回收機制除了檢查物件是否被引用外,還要看物件是否被至少一個GC roots物件直接或者間接引用。GC roots物件包括以下一些類容:

1 每個執行緒當前的函式呼叫棧,從棧頂到棧底的每個函式裡的區域性變數。

2 靜態的變數

3 被jni中引用到的變數。

        所以,上面例子中兩個迴圈引用的物件,雖然都存在一個強引用,但是不被任何GC root物件直接或者間接引用到,垃圾回收機制能夠發現這個問題。

        另外,為了驗證這一點,特意翻看了一下android原始碼中GC管理這一塊的程式碼。在MarkSweep.c這檔案中,有一個void dvmHeapMarkRootSet()函式,這個函式對於GC root物件,有一些詳細的說明,有興趣的可以細看一下。

        所以,java對於迴圈引用有一套自己的解決方案。但是話又說回來,一般實際編碼中出現的迴圈引用不會是上面那個例子那樣明顯,一般都是多個物件複雜的引用導致的迴圈,這個時候,如果一個物件的生命週期很長,就會導致多個物件都釋放不了,所以還是要特別留意物件之間的引用關係。

相關推薦

java物件之間相互迴圈引用例項

在C++中使用過智慧指標的同學們應該都清楚智慧指標對C++中記憶體管理帶來的極大便利,但是也會引入一些頭疼的問題,比如智慧指標帶來的迴圈引用的問題,這個問題在之前的專案中一直沒有很好的解決。         最近參與到android的專案開發,對java的記憶體的管理有了

用JAXB轉換XML和Java物件時的迴圈引用問題的解決方法

    利用JAXB可以實現XML與Java物件之間的轉換。在轉換時,可能會遇到交叉引用的情況,如果不做處理,提示為:     A cycle is detected in the object graph. This will cause infinitely deep

xml與java物件之間相互轉化

Java和xml的互相轉換,依靠強大的JAXBContext可以輕鬆實現。 下面通過一個簡單案例學習一下JAXBContext 首先準備好一個JavaBean供實驗: 注意 1、類檔案註解:@XmlRootElement不可缺少 2、2個Student的構造方法不能少

PHP陣列與物件之間相互轉換

/**  * 陣列 轉 物件  *  * @param array $arr 陣列  * @return object  */ function ar

JSON和JAVA物件之間的轉換小結

    JSON(JAVAScript Object Notation, JS 物件簡譜) 是一種輕量級的資料交換格式。它基於歐洲計算機協會制定的js規範的一個子集,採用完全獨立於程式語言的文字格式來儲存和表示資料。    1.為了便於轉換,需要

AXIS2中OMElement和Java物件之間的轉換 分享

最近在使用AXIS2部署Web Service,關於如果使用axis2部署Web Service的方法不想在這裡多說,網站有很多相關的文章,這裡只想談談AXIOM物件與Java中的物件的轉換方法。 關於AXIOM的介紹,下面這個片段已經說得很明白了: AXIOM AXIs 物件模型 (AXIOM) 是一

利用Google Gson實現JSON字串和物件之間相互轉換

最近一個專案需要用到JSON,需要在JSON字串和物件之間相互轉換,在網上找了些資料,發現google的Gson還是比較不錯的。 廢話不說,下面是簡單的例子: 先上原始碼:下載(包含jar包) Person實體類 package com.hsun.json; /** * Pe

JVM概念之Java物件的大小與引用型別

本文來自和你在一起的部落格,原文標題:《JVM調優總結(二)-一些概念》。本文總結了JVM概念中的Java物件的大小,以及三種引用型別的定義與區分。 基本資料的型別的大小是固定的,這裡就不多說了。對於非基本型別的Java物件,其大小就值得商榷。 在Java中,一個空Obj

json和java物件相互轉換(json-lib和Gson的使用)

在java開發中時常會遇到json與java物件轉換的情況,比如說一般介面呼叫返回的都是json格式的,我們要取出來用就得把它解析成我們想要的格式,有時候我們傳遞引數又需要把引數封裝成json。這兩天

JSON資料和Java物件相互轉換

  * JSON解析器:         * 常見的解析器:Jsonlib,Gson,fastjson,jackson          1. JSON轉為Java物件         1. 匯入jackson的相關jar包         2. 建立Jackson核心物件

Java 物件之間相同屬性的賦值

參考文章 1.BeanUtils.copyProperties import org.springframework.beans.BeanUtils; User src = new User(); User dest = new User(); Bean

json物件java物件相互轉換方法(json-lib、jackson、fastjson、gson)

一 使用json-lib包下的JSONObject和JSONArray轉換 程式碼如下: package com.test.test; import java.util.ArrayList; import java.util.List; import com.cn.e

Java物件記憶體儲存,引用傳遞,值傳遞詳細圖解

問題: Java在呼叫函式時,物件作為引數傳遞,執行函式後引數物件的值是否發生改變。 正文: 在解決這個問題之前首先得說說Java物件在記憶體中的儲存機制。 我們知道Java資料型別基本分為兩種,一是基本型別,還一種是引用型別。 基本型別: 物件型別

JAVA物件之間進行屬性複製的方法比較

  大家在日常的java開發中,經常會使用到物件之間屬性的賦值操作,如果兩個物件之間複製的屬性不多的時候,我們一般都會使用java提供的get、set方法進行復制。但是碰到物件的屬性數量特別多的時候(業務程式碼物件動輒幾十上百個屬性),屬性複製手工輸入上百個ge

XStream實現xml和java物件之間的互相轉換(包括對屬性,別名,下劃線_的處理),同理JSON也可以

首先去官網下載響應JAR包 最少需要兩個jar包,一個xstream.jar,一個是xmlpull.jar 首先來看下java物件到xml的轉換 package xml; class PhoneNumber { private int code;

json:實體類和JSON物件之間相互轉化

在需要用到JSON物件封裝資料的時候,往往會寫很多程式碼,也有很多複製貼上,為了用POJO的思想我們可以裝JSON轉化為實體物件進行操作 1. [程式碼]工具類     packagemyUtil; importjava.io.IOException; impor

Xml字串與C#物件之間相互轉換

我們常常需要讀取xml檔案,把裡面的資訊轉化為我們自定義的型別,或則吧自定義型別轉化為Xml字串。在這裡介紹一個比較簡單的物件轉化方法。在我自己的Framwork裡面也多次用到。裡面涉及到節點、屬性、集合。 示例一 該xml檔案涉及到屬性、節點集合不涉及個節點: <?x

java方法之間引數傳遞(java 程式設計語言對物件採用的是引用呼叫嗎)

java方法之間引數傳遞 基礎型別值傳遞 public static void tripleValue(double x){ x = 3*x; } double value = 10; tripleValue(value); System.out.prin

【JSON 註解】JSON迴圈引用2----JSON註解@JsonIgnoreProperties+JAVA關鍵字transient+後臺物件與JSON資料的格式互相轉化

接著來說這個JSON迴圈引用的問題: @JsonIgnoreProperties({"hibernateLazyInitializer", "org","roles"})  在實體類上註解,在使用jackjson 來解析就行 參考下面 關於JSON格式的轉化,其實關

Java迴圈中建立多個物件是幾個引用?以及是否執行緒安全

在迴圈中,通過User user = new User();這種方式建立的物件。每次建立的物件是不同的,但是引用是同一個,引用的生命週期是單次迴圈,下次迴圈會覆蓋調上次的引用。 比如這段程式碼: int minId = 0; while (