最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解ThreadLocal為什么會內(nèi)存溢出原理

 更新時間:2023年01月04日 14:56:36   作者:Lxlxxx  
這篇文章主要為大家介紹了ThreadLocal為什么會內(nèi)存溢出原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

關(guān)于ThreadLocal (線程本地存儲),從字面意思上看主要是存儲一些本地變量,使它們能在一個線程內(nèi)共用,與其他的線程進行數(shù)據(jù)隔離,保證了數(shù)據(jù)在一個線程內(nèi)的安全性,日常的開發(fā)中,ThreadLocal的使用場景還是比較常見的,包括登陸信息的token的存儲、連接管理一個線程持有一個鏈接,該連接可以在不同的方法之間進行傳遞,一個線程內(nèi)數(shù)據(jù)共享,通過key,value的形式存儲數(shù)據(jù)。

ThreadLocal源碼分析

ThreadLocal類有一個靜態(tài)內(nèi)部類,ThreadLocalMap可以看到內(nèi)部有個Entry 數(shù)組k就是ThreadLocal的引用,Entry 繼承了WeakReference 說明Entry 的k是個弱引用,從這看來如果是弱引用那么就不會存在內(nèi)存溢出,GC運行的時候,這個對象就會被回收掉,value則是存儲的對象,而ThreadLocalMap則是由threadLocals來創(chuàng)建的,可以看到這兩個變量的默認都是NULL。

p>只有當線程第一次調(diào)用的時候才會創(chuàng)建它。

ThreadLocal value內(nèi)存溢出

前面講到ThreadLocal的key是threadlocals是弱引用不會存在內(nèi)存溢出,那么容易存在內(nèi)存溢出的一定是它的value,它與current thread 存在一個強引用的關(guān)系,導(dǎo)致value無法進行回收,如果線程的對象一直不去銷毀這個強引用的對象,那么導(dǎo)致這個關(guān)系一直存在就會出現(xiàn)內(nèi)存溢出,

/**
 * 內(nèi)存溢出例子
 */
public class ThreadLocalTest {
    static class Mytask{
        //定義10m的Byte數(shù)組
       private Byte[] bytes =new Byte[10 *1024 * 1024];
    }
    private static ThreadLocal<Mytask> threadLocal = new ThreadLocal();
    public static void main(String[] args) throws InterruptedException {
        // 5個核心線程、5個最大線程、隊列長度100
        ThreadPoolExecutor threadPoolExecutor =new ThreadPoolExecutor(5, 5, 60,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));
        for (int i = 0; i < 10; i++) {
            //執(zhí)行任務(wù)
            executeTask(threadPoolExecutor);
            Thread.sleep(1000);
        }
    }
    private static void executeTask(ThreadPoolExecutor threadPoolExecutor){
        threadPoolExecutor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("創(chuàng)建Mytask對象");
                Mytask mytask =new Mytask();
                threadLocal.set(mytask);
            }
        });
    }

堆內(nèi)存設(shè)置50m

通過上面代碼,創(chuàng)建線程池對創(chuàng)建的任務(wù),放入threadlocal里面,可以看到出現(xiàn)了堆內(nèi)存的溢出,存放的任務(wù)一直在引用沒有得到釋放導(dǎo)致堆內(nèi)存空間不足。

p>我們在set值到threadLocal后面加入finally,調(diào)用它的remove方法來清除它的內(nèi)存那么就不會發(fā)生內(nèi)存溢出。

來看看remove的代碼,可以看到獲取當前線程的threadLocals,然后調(diào)用remove方法獲取到全部的Entry數(shù)組,判斷不為空,key也是當前的key則調(diào)用clear方法將數(shù)組清除,這樣數(shù)組空間得到了釋放自然就不會出現(xiàn)內(nèi)存溢出。

public void remove() {
    ThreadLocalMap m = getMap(Thread./currentThread/());
    if (m != null)
        m.remove(this);
}
private void remove(ThreadLocal<?> key) {
    Entry[] tab = table;
    int len = tab.length;
    int i = key.threadLocalHashCode & (len-1);
    for (Entry e = tab[i];
         e != null;
         e = tab[i = nextIndex(i, len)]) {
        if (e.get() == key) {
            e.clear();
            expungeStaleEntry(i);
            return;
        }
    }
}

總結(jié)

ThreadLocal在使用的時候一定到進行remove,這也是一個比較常見的內(nèi)存溢出的例子,希望大家引以為戒。

以上就是詳解ThreadLocal為什么會內(nèi)存溢出原理的詳細內(nèi)容,更多關(guān)于ThreadLocal內(nèi)存溢出的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java中?${}?和?#{}?有什么區(qū)別

    java中?${}?和?#{}?有什么區(qū)別

    本文主要介紹了java中${}和#{}有什么區(qū)別,${}和#{}都是MyBatis中用來替換參數(shù)的,它們都可以將用戶傳遞過來的參數(shù),替換到MyBatis最終生成的SQL中,但它們區(qū)別卻是很大的,感興趣的小伙伴可以一起來學(xué)習(xí)下面詳細內(nèi)容
    2022-08-08
  • 淺談Spring bean 生命周期驗證

    淺談Spring bean 生命周期驗證

    本篇文章主要介紹了淺談Spring bean 生命周期驗證,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java國際化簡介_動力節(jié)點Java學(xué)院整理

    Java國際化簡介_動力節(jié)點Java學(xué)院整理

    這篇文章主要為大家簡單介紹了Java國際化的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java Unsafe學(xué)習(xí)筆記分享

    Java Unsafe學(xué)習(xí)筆記分享

    今天小編就為大家分享一篇Java Unsafe學(xué)習(xí)筆記,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java多線程Synchronized實現(xiàn)可見性原理解析

    java多線程Synchronized實現(xiàn)可見性原理解析

    這篇文章主要介紹了java多線程Synchronized實現(xiàn)可見性原理,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • 劍指Offer之Java算法習(xí)題精講二叉樹專題篇下

    劍指Offer之Java算法習(xí)題精講二叉樹專題篇下

    跟著思路走,之后從簡單題入手,反復(fù)去看,做過之后可能會忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會發(fā)現(xiàn)質(zhì)的變化
    2022-03-03
  • java計算兩個日期中間的時間

    java計算兩個日期中間的時間

    這篇文章主要介紹了java計算兩個日期中間的時間的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 解決JSON.toJSONString首字母大小寫的問題

    解決JSON.toJSONString首字母大小寫的問題

    這篇文章主要介紹了解決JSON.toJSONString首字母大小寫的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java基本教程之線程休眠 java多線程教程

    java基本教程之線程休眠 java多線程教程

    本文對javaThread中sleep()方法進行介紹,sleep() 的作用是讓當前線程休眠,即當前線程會從“運行狀態(tài)”進入到“休眠(阻塞)狀態(tài)”,大家參考使用吧
    2014-01-01
  • java實現(xiàn)簡單的客戶信息管理系統(tǒng)

    java實現(xiàn)簡單的客戶信息管理系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單的客戶信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評論

济源市| 洱源县| 全南县| 宁津县| 剑阁县| 淮南市| 通榆县| 惠州市| 宽甸| 新昌县| 右玉县| 苍山县| 洪湖市| 镇安县| 怀仁县| 娱乐| 揭阳市| 阜康市| 宝鸡市| 皮山县| 电白县| 河东区| 宝山区| 乾安县| 肇庆市| 南投县| 丹寨县| 闻喜县| 湖南省| 陵水| 苍山县| 淳安县| 东源县| 砚山县| 公安县| 乌恰县| 远安县| 抚顺县| 西林县| 汉寿县| 泸溪县|