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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 内存泄漏场景_Java内存泄露的例子

發(fā)布時間:2025/5/22 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 内存泄漏场景_Java内存泄露的例子 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在定位JVM性能問題時可能會遇到內(nèi)存泄露導(dǎo)致JVM OutOfMemory的情況,在使用Tomcat容器時如果設(shè)置了reloadable=”true”這個參數(shù),在頻繁熱部署應(yīng)用時也有可能會遇到內(nèi)存溢出的情況。Tomcat的熱部署原理是檢測到WEB-INF/classes或者WEB-INF/lib目錄下的文件發(fā)生了變更后會把應(yīng)用先停止然后再啟動,由于Tomcat默認(rèn)給每個應(yīng)用分配一個WebAppClassLoader,熱替換的原理就是創(chuàng)建一個新的ClassLoader來加載類,由于JVM中一個類的唯一性由它的class文件和它的類加載器來決定,因此重新加載類可以達(dá)到熱替換的目的。當(dāng)熱部署的次數(shù)比較多會導(dǎo)致JVM加載的類比較多,如果之前的類由于某種原因(比如內(nèi)存泄露)沒有及時卸載就可能導(dǎo)致永久代或者MetaSpace的OutOfMemory。這篇文章通過一個Demo來簡要介紹下ThreadLocal和ClassLoader導(dǎo)致內(nèi)存泄露最終OutOfMemory的場景。

類的卸載

在類使用完之后,滿足下面的情形,會被卸載:

該類在堆中的所有實例都已被回收,即在堆中不存在該類的實例對象。

加載該類的classLoader已經(jīng)被回收。

該類對應(yīng)的Class對象沒有任何地方可以被引用,通過反射訪問不到該Class對象。

如果類滿足卸載條件,JVM就在GC的時候,對類進行卸載,即在方法區(qū)清除類的信息。

場景介紹

上一篇文章我介紹了ThreadLocal的原理,每個線程有個ThreadLocalMap,如果線程的生命周期比較長可能會導(dǎo)致ThreadLocalMap里的Entry沒法被回收,那ThreadLocal的那個對象就一直被線程持有強引用,由于實例對象會持有Class對象的引用,Class對象又會持有加載它的ClassLoader的引用,這樣就會導(dǎo)致Class無法被卸載了,當(dāng)加載的類足夠多時就可能出現(xiàn)永久代或者MetaSpace的內(nèi)存溢出,如果該類有大對象,比如有比較大的字節(jié)數(shù)組,會導(dǎo)致Java堆區(qū)的內(nèi)存溢出。

源碼介紹

這里定義了一個內(nèi)部類Inner,Inner類有個靜態(tài)的ThreadLocal對象,主要用于讓線程持有Inner類的強引用導(dǎo)致Inner類無法被回收,定義了一個自定義的類加載器去加載Inner類,如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47public class MemoryLeak{

public static void main(String[] args){

//由于線程一直在運行,因此ThreadLocalMap里的Inner對象一直被Thread對象強引用

new Thread(new Runnable() {

@Override

public void run(){

while (true) {

//每次都新建一個ClassLoader實例去加載Inner類

CustomClassLoader classLoader = new CustomClassLoader

("load1", MemoryLeak.class.getClassLoader(), "com.ezlippi.MemoryLeak$Inner", "com.ezlippi.MemoryLeak$Inner$1");

try {

Class> innerClass = classLoader.loadClass("com.ezlippi.MemoryLeak$Inner");

innerClass.newInstance();

//幫助GC進行引用處理

innerClass = null;

classLoader = null;

Thread.sleep(10);

} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

}

//為了更快達(dá)到堆區(qū)

public static class Inner{

private byte[] MB = new byte[1024 * 1024];

static ThreadLocal threadLocal = new ThreadLocal() {

@Override

protected Inner initialValue(){

return new Inner();

}

};

//調(diào)用ThreadLocal.get()才會調(diào)用initialValue()初始化一個Inner對象

static {

threadLocal.get();

}

public Inner(){

}

}

//源碼省略

private static class CustomClassLoader extends ClassLoader{}

堆區(qū)內(nèi)存溢出

為了觸發(fā)堆區(qū)內(nèi)存溢出,我在Inner類里面設(shè)置了一個1MB的字節(jié)數(shù)組,同時要在靜態(tài)塊中調(diào)用threadLocal.get(),只有調(diào)用才會觸發(fā)initialValue()來初始化一個Inner對象,不然只是創(chuàng)建了一個空的ThreadLocal對象,ThreadLocalMap里并沒有數(shù)據(jù)。

JVM參數(shù)如下:

1-Xms100m -Xmx100m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintClassHistogram -XX:+HeapDumpOnOutOfMemoryError

最后執(zhí)行了814次后JVM堆區(qū)內(nèi)存溢出了,如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20java.lang.OutOfMemoryError: Java heap space

Dumping heap to java_pid11824.hprof ...

Heap dump file created [100661202 bytes in 1.501 secs]

Heap

par new generation total 30720K, used 30389K [0x00000000f9c00000, 0x00000000fbd50000, 0x00000000fbd50000)

eden space 27328K, 99% used [0x00000000f9c00000, 0x00000000fb6ad450, 0x00000000fb6b0000)

from space 3392K, 90% used [0x00000000fb6b0000, 0x00000000fb9b0030, 0x00000000fba00000)

to space 3392K, 0% used [0x00000000fba00000, 0x00000000fba00000, 0x00000000fbd50000)

concurrent mark-sweep generation total 68288K, used 67600K [0x00000000fbd50000, 0x0000000100000000, 0x0000000100000000)

Metaspace used 3770K, capacity 5134K, committed 5248K, reserved 1056768K

class space used 474K, capacity 578K, committed 640K, reserved 1048576K

Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space

at com.ezlippi.MemoryLeak$Inner.(MemoryLeak.java:34)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

at java.lang.reflect.Constructor.newInstance(Unknown Source)

at java.lang.Class.newInstance(Unknown Source)

at com.ezlippi.MemoryLeak$1.run(MemoryLeak.java:20)

at java.lang.Thread.run(Unknown Source)

可以看到JVM已經(jīng)沒有內(nèi)存來創(chuàng)建新的Inner對象,因為堆區(qū)存放了很多個1MB的字節(jié)數(shù)組,這里我把類的直方圖打印出來了(下圖是堆大小為1024M的場景),省略了一些無關(guān)緊要的類,可以看出字節(jié)數(shù)組占了855M的空間,創(chuàng)建了814個com.ezlippi.MemoryLeak$CustomClassLoader的實例,和字節(jié)數(shù)組的大小基本吻合:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21num #instances #bytes class name

----------------------------------------------

1: 6203 855158648 [B

2: 13527 1487984 [C

3: 298 700560 [I

4: 2247 228792 java.lang.Class

5: 8232 197568 java.lang.String

6: 3095 150024 [Ljava.lang.Object;

7: 1649 134480 [Ljava.util.HashMap$Node;

11: 813 65040 com.ezlippi.MemoryLeak$CustomClassLoader

12: 820 53088 [Ljava.util.Hashtable$Entry;

15: 817 39216 java.util.Hashtable

16: 915 36600 java.lang.ref.SoftReference

17: 543 34752 java.net.URL

18: 697 33456 java.nio.HeapCharBuffer

19: 817 32680 java.security.ProtectionDomain

20: 785 31400 java.util.TreeMap$Entry

21: 928 29696 java.util.Hashtable$Entry

22: 1802 28832 java.util.HashSet

23: 817 26144 java.security.CodeSource

24: 814 26048 java.lang.ThreadLocal$ThreadLocalMap$Entry

Metaspace溢出

為了讓Metaspace溢出,那就必須把MetaSpace的空間調(diào)小一點,要在堆溢出之前加載足夠多的類,因此我調(diào)整了下JVM參數(shù),并且把字節(jié)數(shù)組的大小調(diào)成了1KB,如下所示:

1

2

3private byte[] KB = new byte[1024];

-Xms100m -Xmx100m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintClassHistogram -XX:MetaspaceSize=2m -XX:MaxMetaspaceSize=2m

從GC日志可以看出在Meraspace達(dá)到GC閾值(也就是MaxMetaspaceSize配置的大小時)會觸發(fā)一次FullGC:

1

2

3

4

5

6

7

8

9

10

11

12

13java.lang.OutOfMemoryError: Metaspace

<>

{Heap before GC invocations=20 (full 20):

par new generation total 30720K, used 0K [0x00000000f9c00000, 0x00000000fbd50000, 0x00000000fbd50000)

eden space 27328K, 0% used [0x00000000f9c00000, 0x00000000f9c00000, 0x00000000fb6b0000)

from space 3392K, 0% used [0x00000000fb6b0000, 0x00000000fb6b0000, 0x00000000fba00000)

to space 3392K, 0% used [0x00000000fba00000, 0x00000000fba00000, 0x00000000fbd50000)

concurrent mark-sweep generation total 68288K, used 432K [0x00000000fbd50000, 0x0000000100000000, 0x0000000100000000)

Metaspace used 1806K, capacity 1988K, committed 2048K, reserved 1056768K

class space used 202K, capacity 384K, committed 384K, reserved 1048576K

[Full GC (Metadata GC Threshold) [CMS

Process finished with exit code 1

通過上面例子可以看出如果類加載器和ThreadLocal使用的不當(dāng)確實會導(dǎo)致內(nèi)存泄露的問題,完整的源碼在github

總結(jié)

以上是生活随笔為你收集整理的java 内存泄漏场景_Java内存泄露的例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 中文字幕+乱码+中文乱码91 | 久久久久人妻一区精品色 | 欧美一级免费观看 | 亚洲天堂2024 | 国产三级在线观看 | 蜜桃视频久久 | va在线观看| 中文字幕3 | 亚洲第一二三区 | 黄视频网站在线看 | 日韩一区免费 | 男人天堂2021 | 91欧美大片 | 少妇特黄一区二区三区 | 红桃视频在线播放 | 欧美精品午夜 | 国产精品av网站 | 亚洲av无码一区二区乱子仑 | 国内视频精品 | 色综合久久综合 | 欧美中文字幕在线 | 丝袜老师扒开让我了一夜漫画 | 强迫凌虐淫辱の牝奴在线观看 | 欧美精品一区二区三区在线 | 久久人体视频 | 亚洲视频色图 | 丁香婷婷综合激情五月色 | 日本黄xxxxxxxxx100| 久久视精品 | 成年人晚上看的视频 | 96国产精品 | 伊人影院在线视频 | 天天宗合网 | 国产又粗又硬视频 | 亚洲av无码国产精品久久不卡 | 亚洲综合精品在线 | 日本中文在线观看 | 日本在线视频中文字幕 | n0659极腔濑亚美莉在线播放播放 | 国产精品久久久久久久久免费相片 | 性开放的欧美大片 | 人妻少妇精品无码专区久久 | 免费的污网站 | 被黑人各种姿势猛c哭h文1 | 91美女精品| 插插插干干干 | 日本成人在线免费 | 国产精品久久久久久中文字 | 蜜桃av噜噜一区二区三区网址 | 国产成人在线视频免费观看 | 国产精品一区在线免费观看 | 亚洲特黄视频 | 91亚洲精 | 香蕉视频官网在线观看 | 同性色老头性xxxx老头 | 国产精品久久久久久久毛片 | 精品国产乱码久久久久久闺蜜 | 亚欧中文字幕 | 国产精品久久久久久久9999 | 91久| 亚洲黄业 | 成人欧美一区二区三区在线播放 | 亚洲欧美偷拍一区 | 女女综合网 | 国产专区精品 | 中文乱码人妻一区二区三区视频 | 免费古装一级淫片潘金莲 | 中文字幕视频网站 | 国产欧美日韩成人 | 亚洲网站免费观看 | 欧美午夜性生活 | 丁香激情网 | 亚洲狼人综合 | 精品3p | 黄色av电影在线观看 | 91精品久久久久久久久久久 | 亚洲免费久久 | 高h文在线 | a在线免费观看 | 亚洲视频手机在线观看 | 色综合狠狠 | 中国男人操女人 | 女儿的朋友4在线观看 | 五月天久久久久 | 国产制服av | 精品无码久久久久久国产 | 2025国产精品| 欧美国产日韩在线观看 | 无码无遮挡又大又爽又黄的视频 | 人妻少妇精品中文字幕av蜜桃 | 美女久久久久久久久久 | 精品一区二区三 | 又黄又爽视频 | 日本黄色网页 | 免费av黄色| 亚洲第一av网 | 自拍视频国产 | 蜜乳av懂色av粉嫩av | 国产乱淫精品一区二区三区毛片 |