日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

java十分钟速懂知识点——引用

發(fā)布時間:2025/4/16 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java十分钟速懂知识点——引用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、由健忘癥引起的問題

? ? 今天閑來沒事在日志中瞟見了個OutOfMemoryError錯誤,不由得想到前一段時間看到一篇面經(jīng)里問到Java中是否有內(nèi)存泄露,這個很久以前是留意過的,大體記得內(nèi)存溢出和內(nèi)存泄露是不同的,至于各自都有哪些情況,那個...額....忘了...。好吧,記憶力一向不好,忘就忘了,那就再總結(jié)一遍吧。翻了下收藏的博客,回顧了下便是想起了了~.~。看起來一切很美好,但是其中的一個例子突然使我困惑了:

public class TestDemo {static Test[] tests = new Test[3];public static void main(String[] args) {Test t = new Test("test1");tests[0] = t;//將t置為null,看起來似乎我們已經(jīng)釋放創(chuàng)建的對象,當(dāng)下次gc時其將被回收t = null;//那么我們打印下test[0]看看System.out.println(tests[0]);} }

? ? 這是個示例內(nèi)存泄露的例子,該例子十分典型,幾乎所有內(nèi)存泄露的示例都與此類似,作為javaer往往覺得理所應(yīng)當(dāng)。然而作為一個學(xué)習(xí)C++入行(學(xué)的很爛),并一直把引用當(dāng)指針看的javaer不免覺得有些疑惑:t是對象的引用,這里可以看做指向?qū)ο蟮闹羔?#xff0c;那么test[0]=t,按理說應(yīng)該是把t指針賦值給test[0],算是地址傳遞吧,那個t指向null之后,test[0]應(yīng)該也指向null了啊。
? ? 看起來似乎有點道理,然而當(dāng)了解了java的引用之后,發(fā)現(xiàn)吧指針等同于引用是有一些問題的。

二、引用到底是什么

? ? java中的引用到底是什么呢,簡單點說,引用就是存在棧區(qū)的一種特定類型的數(shù)據(jù),其存儲著對象實例在堆區(qū)的地址,其特點如下:

  • 本身是一種數(shù)據(jù)類型,存儲在棧區(qū)
  • 其值存儲著實例對象在堆區(qū)的虛擬地址(注意,是虛擬地址,并不是實際內(nèi)存地址,就如同圖書館里的索引號,不經(jīng)過轉(zhuǎn)換你并不知道書的實際位置
  • 對象在創(chuàng)建未賦值時(無實例),引用會指向null
  • java中參數(shù)傳遞只有值傳遞一種,所謂的引用傳遞傳遞的是引用中存儲的值

? ? 從定義看起來似乎還是區(qū)分不出來引用到底和指針有什么區(qū)別,那么請注意上邊紅字,java為了屏蔽對內(nèi)存直接操作,對對象的實際內(nèi)存地址進行了包裝,從而使引用中的值只能用來找對象,而無法操作內(nèi)存。這一點正是和指最大不同,C++中的指針就是一個真實的內(nèi)存地址,可以通過該地址把內(nèi)存玩出十八般花樣。這點也說明了我們常常把引用傳遞當(dāng)成地址傳遞是錯誤的(雖說實際效果差不多)。

三、上邊的例子到底發(fā)生了什么

? ? 好吧,看了上邊一坨也許你并看不出個什么,也許本身這塊有點繞,也許我說的不清楚,那么我們不如直接畫圖說明上邊那個例子到底發(fā)生了什么(圖示畫的不一定和實際完全一致,只為說明問題),說不定你就明白了:
? ? tests由于是靜態(tài)變量,在類加載完就已經(jīng)實例化了,其在堆內(nèi)存中分配了長度為3的空間,不過值都為null。在創(chuàng)建t之后,t指向了堆內(nèi)存中的對象:


? ? tests[0]=t,這就是我們理解錯誤的地方,這一步test[0]并不是指向t,而是t把Test實例的地址直接賦值給了tests[0],因此tests[0]同樣指向Test實例,這和t已經(jīng)沒有任何關(guān)系了。

? ? 其實從上圖我們就應(yīng)該理解了,t=null之后,其實只是斬斷了t和Test實例的關(guān)系,并沒有改變Test到tests的依賴,從而gc并不會回收Test,這樣就造成了邏輯上的內(nèi)存泄露(為啥說邏輯上,因為明明就是你讓tests還存著Test呢,只是你自以為是的以為釋放了,當(dāng)然,這種意義的泄露和C++所說的內(nèi)存泄露很不同)。

四、只為了結(jié)尾不突兀

? ? 本來是想整理篇內(nèi)存溢出和內(nèi)存泄露的,順便寫下這塊,但是發(fā)現(xiàn)并不是太好說清楚,就單寫了。好了,就這樣吧,原來JVM學(xué)習(xí)總結(jié)系列寫了一半扔那了,現(xiàn)在發(fā)現(xiàn)還是挺有意思的,有空接著寫吧。



轉(zhuǎn)載于:https://www.cnblogs.com/good-temper/p/4916063.html

總結(jié)

以上是生活随笔為你收集整理的java十分钟速懂知识点——引用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。