中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

陜西網(wǎng)站建設(shè)公司哪有網(wǎng)絡(luò)推廣都是收費(fèi)

陜西網(wǎng)站建設(shè)公司哪有,網(wǎng)絡(luò)推廣都是收費(fèi),常州外貿(mào)集團(tuán) 網(wǎng)站建設(shè),上海公司注冊(cè)地址預(yù)備知識(shí)(引用) Object o new Object(); 這個(gè)o,我們可以稱之為對(duì)象引用,而new Object()我們可以稱之為在內(nèi)存中產(chǎn)生了一個(gè)對(duì)象實(shí)例。 當(dāng)寫下 onull時(shí),只是表示o不再指向堆中object的對(duì)象實(shí)例,不代表這個(gè)…

預(yù)備知識(shí)(引用)

Object o = new Object();

這個(gè)o,我們可以稱之為對(duì)象引用,而new Object()我們可以稱之為在內(nèi)存中產(chǎn)生了一個(gè)對(duì)象實(shí)例。

當(dāng)寫下?o=null時(shí),只是表示o不再指向堆中object的對(duì)象實(shí)例,不代表這個(gè)對(duì)象實(shí)例不存在了。

  • 強(qiáng)引用:?就是指在程序代碼之中普遍存在的,類似“Object obj=new Object()”這類的引用,只要強(qiáng)引用還存在,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象實(shí)例。

  • 軟引用:?是用來(lái)描述一些還有用但并非必需的對(duì)象。對(duì)于軟引用關(guān)聯(lián)著的對(duì)象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常之前,將會(huì)把這些對(duì)象實(shí)例列進(jìn)回收范圍之中進(jìn)行第二次回收。如果這次回收還沒(méi)有足夠的內(nèi)存,才會(huì)拋出內(nèi)存溢出異常。在JDK 1.2之后,提供了SoftReference類來(lái)實(shí)現(xiàn)軟引用。

  • 弱引用:?也是用來(lái)描述非必需對(duì)象的,但是它的強(qiáng)度比軟引用更弱一些,被弱引用關(guān)聯(lián)的對(duì)象實(shí)例只能生存到下一次垃圾收集發(fā)生之前。當(dāng)垃圾收集器工作時(shí),無(wú)論當(dāng)前內(nèi)存是否足夠,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象實(shí)例。在JDK 1.2之后,提供了WeakReference類來(lái)實(shí)現(xiàn)弱引用。

  • 虛引用:?也稱為幽靈引用或者幻影引用,它是最弱的一種引用關(guān)系。一個(gè)對(duì)象實(shí)例是否有虛引用的存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無(wú)法通過(guò)虛引用來(lái)取得一個(gè)對(duì)象實(shí)例。為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象實(shí)例被收集器回收時(shí)收到一個(gè)系統(tǒng)通知。在之后,提供了類來(lái)實(shí)現(xiàn)虛引用

內(nèi)存泄漏的現(xiàn)象

/*** 類說(shuō)明:ThreadLocal造成的內(nèi)存泄漏演示*/
public class ThreadLocalOOM {private static final int TASK_LOOP_SIZE = 500;final static ThreadPoolExecutor poolExecutor= new ThreadPoolExecutor(5, 5,1,TimeUnit.MINUTES,new LinkedBlockingQueue<>());static class LocalVariable {private byte[] a = new byte[1024*1024*5];/*5M大小的數(shù)組*/}final static ThreadLocal<LocalVariable> localVariable= new ThreadLocal<>();public static void main(String[] args) throws InterruptedException {Object o = new Object();/*5*5=25*/for (int i = 0; i < TASK_LOOP_SIZE; ++i) {poolExecutor.execute(new Runnable() {public void run() {//localVariable.set(new LocalVariable());new LocalVariable();System.out.println("use local varaible");//localVariable.remove();}});Thread.sleep(100);}System.out.println("pool execute over");}}

首先只簡(jiǎn)單的在每個(gè)任務(wù)中new出一個(gè)數(shù)組

?可以看到內(nèi)存的實(shí)際使用控制在25M左右:因?yàn)槊總€(gè)任務(wù)中會(huì)不斷new出一個(gè)5M的數(shù)組,5*5=25M,這是很合理的。

當(dāng)我們啟用了ThreadLocal以后

?

內(nèi)存占用最高升至150M,一般情況下穩(wěn)定在90M左右,那么加入一個(gè)ThreadLocal后,內(nèi)存的占用真的會(huì)這么多?

于是,我們加入一行代碼:

?再執(zhí)行,看看內(nèi)存情況:

可以看見(jiàn)最高峰的內(nèi)存占用也在25M左右,完全和我們不加ThreadLocal表現(xiàn)一樣。

這就充分說(shuō)明,確實(shí)發(fā)生了內(nèi)存泄漏。

分析

根據(jù)我們前面對(duì)ThreadLocal的分析,我們可以知道每個(gè)Thread 維護(hù)一個(gè) ThreadLocalMap,這個(gè)映射表的 key 是 ThreadLocal實(shí)例本身,value 是真正需要存儲(chǔ)的 Object,也就是說(shuō) ThreadLocal 本身并不存儲(chǔ)值,它只是作為一個(gè) key 來(lái)讓線程從 ThreadLocalMap 獲取 value。仔細(xì)觀察ThreadLocalMap,這個(gè)map是使用 ThreadLocal 的弱引用作為 Key 的,弱引用的對(duì)象在 GC 時(shí)會(huì)被回收。

因此使用了ThreadLocal后,引用鏈如圖所示

圖中的虛線表示弱引用。

? 這樣,當(dāng)把threadlocal變量置為null以后,沒(méi)有任何強(qiáng)引用指向threadlocal實(shí)例,所以threadlocal將會(huì)被gc回收。這樣一來(lái),ThreadLocalMap中就會(huì)出現(xiàn)key為null的Entry,就沒(méi)有辦法訪問(wèn)這些key為null的Entry的value,如果當(dāng)前線程再遲遲不結(jié)束的話,這些key為null的Entry的value就會(huì)一直存在一條強(qiáng)引用鏈:

Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value,而這塊value永遠(yuǎn)不會(huì)被訪問(wèn)到了,所以存在著內(nèi)存泄露。

? 只有當(dāng)前thread結(jié)束以后,current thread就不會(huì)存在棧中,強(qiáng)引用斷開,Current Thread、Map value將全部被GC回收。最好的做法是不在需要使用ThreadLocal變量后,都調(diào)用它的remove()方法,清除數(shù)據(jù)。

? 其實(shí)考察ThreadLocal的實(shí)現(xiàn),我們可以看見(jiàn),無(wú)論是get()、set()在某些時(shí)候,調(diào)用了expungeStaleEntry方法用來(lái)清除Entry中Key為null的Value,但是這是不及時(shí)的,也不是每次都會(huì)執(zhí)行的,所以一些情況下還是會(huì)發(fā)生內(nèi)存泄露。只有remove()方法中顯式調(diào)用了expungeStaleEntry方法。

? 從表面上看內(nèi)存泄漏的根源在于使用了弱引用,但是另一個(gè)問(wèn)題也同樣值得思考:為什么使用弱引用而不是強(qiáng)引用?

下面我們分兩種情況討論:

??key 使用強(qiáng)引用:引用ThreadLocal的對(duì)象被回收了,但是ThreadLocalMap還持有ThreadLocal的強(qiáng)引用,如果沒(méi)有手動(dòng)刪除,ThreadLocal的對(duì)象實(shí)例不會(huì)被回收,導(dǎo)致Entry內(nèi)存泄漏。

??key 使用弱引用:引用的ThreadLocal的對(duì)象被回收了,由于ThreadLocalMap持有ThreadLocal的弱引用,即使沒(méi)有手動(dòng)刪除,ThreadLocal的對(duì)象實(shí)例也會(huì)被回收。value在下一次ThreadLocalMap調(diào)用set,get,remove都有機(jī)會(huì)被回收。

? 比較兩種情況,我們可以發(fā)現(xiàn):由于ThreadLocalMap的生命周期跟Thread一樣長(zhǎng),如果都沒(méi)有手動(dòng)刪除對(duì)應(yīng)key,都會(huì)導(dǎo)致內(nèi)存泄漏,但是使用弱引用可以多一層保障。

? 因此,ThreadLocal內(nèi)存泄漏的根源是:由于ThreadLocalMap的生命周期跟Thread一樣長(zhǎng),如果沒(méi)有手動(dòng)刪除對(duì)應(yīng)key就會(huì)導(dǎo)致內(nèi)存泄漏,而不是因?yàn)槿跻谩?/p>

為什么ThreadLocalMap的key要設(shè)置為弱引用?

在 ThreadLocalMap 中的set和get方法中,會(huì)對(duì) key為null進(jìn)行判斷,如果key為null會(huì)把value也置為null。
這樣就算忘記調(diào)用remove方法,對(duì)應(yīng)的value在下次調(diào)用get、set、remove方法中的任意一個(gè)都會(huì)被清除,從而避免內(nèi)存泄漏(相當(dāng)于多了一層保障,但是如果后續(xù)一直不調(diào)用這些方法,依然存在內(nèi)存泄漏的風(fēng)險(xiǎn),所以最好是及時(shí)remove)。

總結(jié)

? JVM利用設(shè)置ThreadLocalMap的Key為弱引用,來(lái)避免內(nèi)存泄露。

JVM利用調(diào)用remove、get、set方法的時(shí)候,回收弱引用。

當(dāng)ThreadLocal存儲(chǔ)很多Key為null的Entry的時(shí)候,而不再去調(diào)用remove、get、set方法,那么將導(dǎo)致內(nèi)存泄漏。

使用線程池+?ThreadLocal?時(shí)要小心,因?yàn)檫@種情況下,線程是一直在不斷的重復(fù)運(yùn)行的,從而也就造成了value可能造成累積的情況。

錯(cuò)誤使用ThreadLocal導(dǎo)致線程不安全

/*** 非安全的ThreadLocal 演示*/
public class ThreadLocalUnsafe implements Runnable {public static ThreadLocal<Number> numberThreadLocal = new ThreadLocal<Number>();/*** 使用threadLocal的靜態(tài)變量*/public static Number number = new Number(0);public void run() {//每個(gè)線程計(jì)數(shù)加一number.setNum(number.getNum() + 1);//將其存儲(chǔ)到ThreadLocal中numberThreadLocal.set(number);//延時(shí)2mstry {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//輸出num值System.out.println("內(nèi)存地址:"+numberThreadLocal.get() + "," + Thread.currentThread().getName() + "=" + numberThreadLocal.get().getNum());}public static void main(String[] args) {for (int i = 0; i < 5; i++) {new Thread(new ThreadLocalUnsafe()).start();}}/*** 一個(gè)私有的類 Number*/private static class Number {public Number(int num) {this.num = num;}private int num;public int getNum() {return num;}public void setNum(int num) {this.num = num;}}
}

?輸出:

內(nèi)存地址:com.test.thread.ThreadLocalUnsafe$Number@5658172e,Thread-2=5
內(nèi)存地址:com.test.thread.ThreadLocalUnsafe$Number@5658172e,Thread-0=5
內(nèi)存地址:com.test.thread.ThreadLocalUnsafe$Number@5658172e,Thread-4=5
內(nèi)存地址:com.test.thread.ThreadLocalUnsafe$Number@5658172e,Thread-1=5
內(nèi)存地址:com.test.thread.ThreadLocalUnsafe$Number@5658172e,Thread-3=5

? 為什么每個(gè)線程都輸出5?難道他們沒(méi)有獨(dú)自保存自己的Number副本嗎?為什么其他線程還是能夠修改這個(gè)值?仔細(xì)考察下我們的代碼,我們發(fā)現(xiàn)我們的number對(duì)象是靜態(tài)的,所以每個(gè)ThreadLoalMap中保存的其實(shí)同一個(gè)對(duì)象的引用,這樣的話,當(dāng)有其他線程對(duì)這個(gè)引用指向的對(duì)象實(shí)例做修改時(shí),其實(shí)也同時(shí)影響了所有的線程持有的對(duì)象引用所指向的同一個(gè)對(duì)象實(shí)例。這也就是為什么上面的程序?yàn)槭裁磿?huì)輸出一樣的結(jié)果:5個(gè)線程中保存的是同一Number對(duì)象的引用,在線程睡眠的時(shí)候,其他線程將num變量進(jìn)行了修改,而修改的對(duì)象Number的實(shí)例是同一份,因此它們最終輸出的結(jié)果是相同的。

而上面的程序要正常的工作,應(yīng)該去掉number的static 修飾,讓每個(gè)ThreadLoalMap中使用不同的number對(duì)象進(jìn)行操作。

總結(jié):ThreadLocal只保證線程隔離,不保證線程安全。

http://www.risenshineclean.com/news/3470.html

相關(guān)文章:

  • 網(wǎng)絡(luò)優(yōu)化崗位詳細(xì)介紹網(wǎng)絡(luò)優(yōu)化工程師騙局
  • 化妝品網(wǎng)站開發(fā)的背景微信做單30元一單
  • 網(wǎng)站開發(fā)的前后端是哪些搜索引擎營(yíng)銷的常見(jiàn)方式
  • 廣州微信網(wǎng)站建設(shè)哪家好經(jīng)典軟文案例或軟文案例
  • 美工素材網(wǎng)站有哪些百度北京總部電話
  • 長(zhǎng)泰縣建設(shè)局網(wǎng)站電腦培訓(xùn)課程
  • 做網(wǎng)站需要Excel表格嗎國(guó)際新聞 軍事
  • 網(wǎng)站改版的宣傳詞湖南網(wǎng)絡(luò)優(yōu)化服務(wù)
  • wordpress做登陸頁(yè)面模板林哥seo
  • 做高仿表網(wǎng)站免費(fèi)seo公司
  • 做百度推廣會(huì)送網(wǎng)站嗎線上營(yíng)銷渠道主要有哪些
  • 現(xiàn)在花錢做那個(gè)網(wǎng)站好呀北京搜索優(yōu)化排名公司
  • 個(gè)人網(wǎng)站能備案嗎中國(guó)品牌策劃公司排名
  • 網(wǎng)站建設(shè)報(bào)價(jià)單模板下載如何做好網(wǎng)站的推廣工作
  • 可以做軟件的網(wǎng)站有哪些中文域名注冊(cè)管理中心
  • 運(yùn)城網(wǎng)站建設(shè)求職簡(jiǎn)歷市場(chǎng)營(yíng)銷一般在哪上班
  • 中英雙文網(wǎng)站怎么做磁力搜索器下載
  • 合肥做兼職網(wǎng)站開魯seo服務(wù)
  • 如何用dw建立網(wǎng)站互聯(lián)網(wǎng)域名交易中心
  • 關(guān)于做甜品的網(wǎng)站站長(zhǎng)工具seo綜合查詢問(wèn)題
  • 如何做直播網(wǎng)站有沒(méi)有專門幫人推廣的公司
  • 上海專業(yè)網(wǎng)站建設(shè)公司電話四川seo多少錢
  • 自己做的網(wǎng)站怎么掛廣告上海百度推廣開戶
  • 東莞廣告公司有哪些長(zhǎng)沙seo優(yōu)化公司
  • 北京多用戶商城網(wǎng)站建設(shè)百度愛(ài)采購(gòu)優(yōu)化排名軟件
  • 幫人做網(wǎng)站一個(gè)多少錢網(wǎng)站在線推廣
  • 免費(fèi)企業(yè)網(wǎng)站模板psd站長(zhǎng)之家是干什么的
  • 南通快速建站公司公司建網(wǎng)站多少錢
  • 南寧建設(shè)廳網(wǎng)站是什么效果好的關(guān)鍵詞如何優(yōu)化
  • 百度指數(shù)官網(wǎng)入口網(wǎng)站在線優(yōu)化檢測(cè)