<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                http://blog.csdn.net/hudashi/article/details/7076880 ThreadLocal的目的就是為每一個使用ThreadLocal的線程都提供一個值,讓該值和使用它的線程綁定,當然每一個線程都可以獨立地改變它綁定的值。如果需要隔離多個線程之間的共享沖突,可以使用ThreadLocal,這將極大地簡化你的程序. 關于的ThreadLocal更多內容,請參考《ThreadLocal》。 在閱讀了ThreadLocal的源碼后,我發現如果我們使用不恰當,可能造成內存泄露。經我測試,內存泄露的確存在。雖然該內存泄露,理論上上已經不算嚴重。 測試代碼如下 ThreadLocalTest文件 ~~~ package com.teleca.robin; public class ThreadLocalTest { public ThreadLocalTest() { } ThreadLocal<Content> tl=new ThreadLocal<Content> (); void start() { System.out.println("begin"); Content content=tl.get(); if(content==null) { content= new Content(); tl.set(content); } System.out.println("try to release content data"); //tl.set(null);//@1 //tl.remove();//@2 tl=null;//@3 content=null;//@4 System.out.println("request gc"); System.gc(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("end"); } } class Content { byte data[]=new byte[1024*1024*10]; protected void finalize() { System.out.println("I am released"); } } ~~~ 運行結果 ~~~ begin try to release content data request gc end ~~~ 注意我們嘗試在@3和@4處,釋放對tl和content的引用,以便JAVA虛擬機回收content。但是測試結果表明還有對content的引用,以致它沒有能被JAVA虛擬機回收。 我們必須把@1或@2處的代碼打開,才能把讓它讓JAVA虛擬機回收content.推薦打開@2而不是@1 把@1或@2處的代碼打開后的運行結果如下: ~~~ begin try to release content data request gc I am released end ~~~ 另外注意,@3其實并不影響運行結果。 事實上每個Thread實例都有一個ThreadLocalMap成員變量,它以ThreadLocal對象為key,以ThreadLocal綁定的對象為Value。 .我們調用ThreadLocal的set()方法,只是把要綁定的對象存放在當前線程的ThreadLocalMap成員變量中,以便下次通過get()方法取得它。 ThreadLocalMap和普通map的最大區別就是它的Entry是針對ThreadLocal弱引用的,即當ThreadLocal沒有其他引用為空時,JVM就可以GC回收ThreadLocal,從而得到一個null的key。 關于ThreadLocalMap的更多內容請參考《為ThreadLocal定制的ThreadLocalMap》 ThreadlocalMap維護了ThreadLocal對象和其綁定對象之間的關系,這個ThreadLocalMap有threshold,當超過threshold時, ThreadLocalMap會首先檢查內部ThreadLocal引用(前文說過,ThreadLocal是弱引用可以釋放)是否為null,如果存在null,那么把綁定對象的引用設置為null,以便釋放ThreadLocal綁定的對象,這樣就騰出了位置給新的ThreadLocal。如果不存在slate threadlocal,那么double threshold。 除此之外,還有兩個機會釋放掉已經廢棄的ThreadLocal綁定的對象所占用的內存, 一、當hash算法得到的table index剛好是一個null 的key的threadlocal時,直接用新的ThreadLocal替換掉已經廢棄的。 二、每次在ThreadLocalMap中存放ThreadLocal,hash算法沒有命中既有Entry,需要新建一個Entry時,也調用cleanSomeSlots來遍歷清理Entry數組中已經廢棄的ThreadLocal綁定的對象的引用。 此外,當Thread本身銷毀時,這個ThreadLocalMap也一定被銷毀了(ThreadLocalMap是Thread對象的成員), 這樣所有綁定到該線程的ThreadLocal的Object Value對象,如果在外部沒被引用的話(通常是這樣),也就沒有任何引用繼續保持,所以也就被銷毀回收了。 從上可以看出Java已經充分考慮了時間和空間的權衡,但是因為置為null的ThreadLocal對應的Object Value在無外部引用時,任然無法及時回收。 ThreadLocalMap只有到達threshold時或添加entry時才做檢查,不似gc是定時檢查, 不過我們可以手工通過ThreadLocal的remove()方法或set(null)解除ThreadLocalMap對ThreadLocal綁定對象的引用,及時的清理廢棄的threadlocal綁定對象的內存以。remove()往往還能做更多的清理工作,因此推薦使用它,而不使用set(null). 需要說明的是,只要不往不用的threadlocal中放入大量數據,問題不大,畢竟還有回收的機制。 被廢棄了的ThreadLocal所綁定對象的引用,會在以下4情況被清理。 如果此時外部沒有綁定對象的引用,則該綁定對象就能被回收了: 1 Thread結束時。 2 當Thread的ThreadLocalMap的threshold超過最大值時。 3 向Thread的ThreadLocalMap中存放一個ThreadLocal,hash算法沒有命中既有Entry,而需要新建一個Entry時。 4 手工通過ThreadLocal的remove()方法或set(null)。 因此如果我們粗暴的把ThreadLocal設置null,而不調用remove()方法或set(null),那么就可能造成ThreadLocal綁定的對象長期也能被回收,因而產出內存泄露。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看