成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何用Java編寫一段代碼引發內存泄露

開發 后端
剛才我參加了面試,面試官問我如何寫出會發生內存泄露的Java代碼。這個問題我一點思路都沒有,好囧。

Q:剛才我參加了面試,面試官問我如何寫出會發生內存泄露的Java代碼。這個問題我一點思路都沒有,好囧。

A1:通過以下步驟可以很容易產生內存泄露(程序代碼不能訪問到某些對象,但是它們仍然保存在內存中):

如何用Java編寫一段代碼引發內存泄露

  1. 應用程序創建一個長時間運行的線程(或者使用線程池,會更快地發生內存泄露)。

  2. 線程通過某個類加載器(可以自定義)加載一個類。

  3. 該類分配了大塊內存(比如new byte[1000000]),在某個靜態變量存儲一個強引用,然后在ThreadLocal中存儲它自身的引用。分配額外的內存new byte[1000000]是可選的(類實例泄露已經足夠了),但是這樣會使內存泄露更快。

  4. 線程清理自定義的類或者加載該類的類加載器。

  5. 重復以上步驟。

由于沒有了對類和類加載器的引用,ThreadLocal中的存儲就不能被訪問到。ThreadLocal持有該對象的引用,它也就持有了這個類及 其類加載器的引用,類加載器持有它所加載的類的所有引用,這樣GC無法回收ThreadLocal中存儲的內存。在很多JVM的實現中Java類和類加載 器直接分配到permgen區域不執行GC,這樣導致了更嚴重的內存泄露。

這種泄露模式的變種之一就是如果你經常重新部署以任何形式使用了ThreadLocal的應用程序、應用容器(比如Tomcat)會很容易發生內存泄露(由于應用容器使用了如前所述的線程,每次重新部署應用時將使用新的類加載器)。

A2:

靜態變量引用對象

class MemorableClass {
    static final ArrayList list = new ArrayList(100);
}

調用長字符串的String.intern()

String str=readString(); // read lengthy string any source db,textbox/jsp etc..
// This will place the string in memory pool from which you cant remove
str.intern();

未關閉已打開流(文件,網絡等)

try {
    BufferedReader br = new BufferedReader(new FileReader(inputFile));
    ...
    ...
} catch (Exception e) {
    e.printStacktrace();
}

未關閉連接

try {
    Connection conn = ConnectionFactory.getConnection();
    ...
    ...
} catch (Exception e) {
    e.printStacktrace();
}

JVM的GC不可達區域

比如通過native方法分配的內存。

web應用在application范圍的對象,應用未重啟或者沒有顯式移除

getServletContext().setAttribute("SOME_MAP", map);

web應用在session范圍的對象,未失效或者沒有顯式移除

session.setAttribute("SOME_MAP", map);

不正確或者不合適的JVM選項

比如IBM JDK的noclassgc阻止了無用類的垃圾回收

A3:如果HashSet未正確實現(或者未實現)hashCode()或者equals(),會導致集合中持續增加“副本”。如果集合不能地忽略掉它應該忽略的元素,它的大小就只能持續增長,而且不能刪除這些元素。

如果你想要生成錯誤的鍵值對,可以像下面這樣做:

class BadKey {
   // no hashCode or equals();
   public final String key;
   public BadKey(String key) { this.key = key; }
}

Map map = System.getProperties();
map.put(new BadKey("key"), "value"); // Memory leak even if your threads die.

A4:除了被遺忘的監聽器,靜態引用,hashmap中key錯誤/被修改或者線程阻塞不能結束生命周期等典型內存泄露場景,下面介紹一些不太明顯的Java發生內存泄露的情況,主要是線程相關的。

  • Runtime.addShutdownHook后沒有移除,即使使用了removeShutdownHook,由于ThreadGroup類對于未啟動線程的bug,它可能不被回收,導致ThreadGroup發生內存泄露。
  • 創建但未啟動線程,與上面的情形相同
  • 創建繼承了ContextClassLoader和AccessControlContext的線程,ThreadGroup和InheritedThreadLocal的使用,所有這些引用都是潛在的泄露,以及所有被類加載器加載的類和所有靜態引用等等。這對ThreadFactory接口作為重要組成元素整個j.u.c.Executor框架(java.util.concurrent)的影響非常明顯,很多開發人員沒有注意到它潛在的危險。而且很多庫都會按照請求啟動線程。
  • ThreadLocal緩存,很多情況下不是好的做法。有很多基于ThreadLocal的簡單緩存的實現,但是如果線程在它的期望生命周期外繼續運行ContextClassLoader將發生泄露。除非真正必要不要使用ThreadLocal緩存。
  • 當ThreadGroup自身沒有線程但是仍然有子線程組時調用ThreadGroup.destroy()。發生內存泄露將導致該線程組不能從它的父線程組移除,不能枚舉子線程組。
  • 使用WeakHashMap,value直接(間接)引用key,這是個很難發現的情形。這也適用于繼承Weak/SoftReference的類可能持有對被保護對象的強引用。
  • 使用http(s)協議的java.net.URL下載資源。KeepAliveCache在系統ThreadGroup創建新線程,導致當前線程的上下文類加載器內存泄露。沒有存活線程時線程在***次請求時創建,所以很有可能發生泄露。(在Java7中已經修正了,創建線程的代碼合理地移除了上下文類加載器。)
  • 使用InflaterInputStream在構造函數(比如PNGImageDecoder)中傳遞new java.util.zip.Inflater(),不調用inflater的end()。僅僅是new的話非常安全,但如果自己創建該類作為構造函數參數時調用流的close()不能關閉inflater,可能發生內存泄露。這并不是真正的內存泄露因為它會被finalizer釋放。但這消耗了很多native內存,導致linux的oom_killer殺掉進程。所以這給我們的教訓是:盡可能早地釋放native資源。
  • java.util.zip.Deflater也一樣,它的情況更加嚴重。好的地方可能是很少用到Deflater。如果自己創建了Deflater或者Inflater記住必須調用end()。

 

責任編輯:王雪燕 來源: ImportNew - hejiani
相關推薦

2020-04-03 10:14:57

內存蠕蟲代碼web安全

2022-06-21 12:27:12

JavaScript前端

2018-06-23 08:02:31

程序員代碼故事

2021-08-10 05:49:10

網絡協議C語言Linux操作

2014-07-08 09:21:10

死代碼創意歌曲

2020-10-26 10:11:45

Jupyter Not早起Python開發

2020-12-31 10:14:42

防注入代碼繞過

2018-06-19 08:02:00

統計程序微信

2021-02-04 07:55:28

代碼離職互聯網

2013-10-11 13:36:46

2021-07-26 23:39:20

Java變量代碼

2020-04-29 10:19:29

Python數據函數

2025-03-04 04:00:00

C++代碼windows

2018-11-02 16:16:41

程序硬盤存儲

2015-12-07 09:39:27

Java內存泄露

2020-12-16 07:42:03

JS基礎代碼

2017-12-11 11:00:27

內存泄露判斷

2012-03-15 13:36:51

云計算JavaSpring框架

2014-03-21 09:58:08

比特幣

2019-06-19 10:57:48

新人入職代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品日韩一区二区三区av动图 | 成人精品一区二区三区 | 91精品国产综合久久国产大片 | 欧美精品91 | 国产欧美一区二区三区另类精品 | 国产精品免费视频一区 | a在线观看 | 国产成人小视频 | 国产美女免费视频 | 黄色一级大片在线免费看产 | 久久久久久久国产 | 久久精品亚洲 | 国产a区| 国产丝袜一区二区三区免费视频 | 亚洲精品99 | 欧美日韩在线一区二区 | 成人免费av | 日韩欧美一级 | 欧美在线一区二区三区 | 国产在线小视频 | 亚洲午夜精品一区二区三区 | 国产午夜精品一区二区三区嫩草 | 九一视频在线观看 | 中文字幕久久精品 | 久久aⅴ乱码一区二区三区 亚洲欧美综合精品另类天天更新 | 欧美三级视频在线观看 | 亚洲毛片 | www国产成人免费观看视频,深夜成人网 | 91一区二区三区 | 黄色骚片 | 国产一区二区三区在线 | 亚洲日韩中文字幕一区 | 久久精品视频在线播放 | 狠狠操狠狠搞 | 精品成人佐山爱一区二区 | 毛片在线视频 | 日本又色又爽又黄的大片 | 日韩国产精品一区二区三区 | 人人草人人干 | 国产一区二区自拍 | 精品国产乱码久久久久久88av |