2016-12-07 51 views
0

在我的應用程序中,我使用javassist庫在運行時創建了大量的java類。在某個時候拋出了一個java.lang.OutOfMemoryError: Metaspace,但java進程監視(基於java.lang.management.MemoryPoolMXBean)報告有很多免費的metaspace。這是爲什麼?以及如何使用100%的metaspace內存池?爲什麼Java會拋出java.lang.OutOfMemoryError:Metaspace,但有很多免費的元組空間?

我創建了一個最小的應用程序能重現問題https://github.com/vlkv/java_metaspace_oom

Donwload它,cd到項目目錄,然後執行「螞蟻跑」。在這個應用程序中,我已經設置了-XX:MaxMetaspaceSize = 100m,但是在使用元代空間23564Kb的某個點引發了OOM。錯誤的

調用堆棧是:

javassist.CannotCompileException: by java.lang.OutOfMemoryError: Metaspace 
    at javassist.ClassPool.toClass(ClassPool.java:1170) 
    at javassist.CtClass.toClass(CtClass.java:1316) 
    at com.tradingview.Main.generateRandomClass(Main.java:53) 
    at com.tradingview.Main.main(Main.java:24) 
Caused by: java.lang.OutOfMemoryError: Metaspace 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642) 
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at javassist.ClassPool.toClass2(ClassPool.java:1183) 
    at javassist.ClassPool.toClass(ClassPool.java:1164) 
    ... 3 more 
+1

時的內存要求*量超過*的可用空間,則拋出該異常。不是當空閒空間爲零時。 – EJP

+0

@EJP根據OP,在拋出異常時仍然有一些可用空間可用 – qxz

+0

@vitvlkv您是否調試過它以查看程序中異常來自哪裏?小心提供[最小,完整,可驗證示例](http://stackoverflow.com/help/mcve)? – qxz

回答

-1

哇,我剛剛找到了答案。 問題是,在我的應用程序中,我爲每個生成的類創建了一個單獨的新ClassLoader。我在我的示例應用程序中進行了修改,將所有生成的類放到一個ClassLoader中,之後,在空閒元數據幾乎爲零時拋出OOM。修復在這裏https://github.com/vlkv/java_metaspace_oom/commit/d6bcade51f79758e2413d1852c771f163392c294分支fix_of_the_problem

有人知道java進程中類加載器的限制是什麼嗎?以及如何增加它們?

也發現了這個Why MetaSpace Size is twice as big as Used MetaSpace?

+0

請解釋'充足的免費元空間'和'免費元空間幾乎爲零'之間的矛盾。 – EJP

+0

@EJP http://www.dictionary.com/browse/plenty – vitvlkv

相關問題