java.lang.OutOfMemoryError
由于内存泄漏,应用程序可能无法使用java.lang.OutOfMemoryError:Metaspace
元空间异常
已知在以下情况下会发生此问题:
- 应用程序的部署
- mule服务器的启动
INFO 2019-01-08 19:24:36,067 [Mule.app.deployer.monitor.1.thread.1] [event: ] org.mule.runtime.module.deployment.internal.ArtifactArchiveInstaller: Exploding a Mule artifact archive: /opt/mule_runtime/mule-enterprise-standalone-4.1.4 2/apps/testleakappsimple3.jar
java.lang.OutOfMemoryError: Metaspace
Dumping heap to java_pid13617.hprof ...
Heap dump file created [354927008 bytes in 2.172 secs]
ERROR 2019-01-08 19:24:40,471 [Mule.app.deployer.monitor.1.thread.1] [event: ] org.mule.runtime.module.deployment.internal.DefaultArchiveDeployer:
在这些情况下,应用程序的部署将失败。如果在启动过程中,服务器可能无法启动。
在执行HTTP请求期间,应用程序日志文件中可能会出现以下或类似错误。HTTP请求将失败。
org.mule.runtime.core.internal.exception.OnCriticalErrorHandler:
********************************************************************************
Message : Metaspace.
Error type : MULE:CRITICAL
..
..
..
org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
********************************************************************************
Message : java.lang.OutOfMemoryError: Metaspace.
Error type : MULE:FATAL_JVM_ERROR
..
..
..
org.mule.runtime.core.internal.exception.DefaultSystemExceptionStrategy: Caught exception in Exception Strategy: java.lang.OutOfMemoryError: Metaspace
org.mule.runtime.api.exception.MuleFatalException: java.lang.OutOfMemoryError: Metaspace
Caused by: java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_181]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_181]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_181]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[?:1.8.0_181]
at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[?:1.8.0_181]
at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[?:1.8.0_181]
at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[?:1.8.0_181]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_181]
at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[?:1.8.0_181]
at org.mule.runtime.module.artifact.api.classloader.FineGrainedControlClassLoader.findLocalClass(FineGrainedControlClassLoader.java:167) ~[mule-module-artifact-4.1.4.jar:4.1.4]
注意:这是一个与OutOfMemory
完全不同的问题:堆错误。
原因:
这是由于元空间metaspace
的内存分配不足造成的。Mulesoft正在调查mule4
是否可以进一步调整以避免这个问题。
受影响的产品
Mule
运行时4.1.4
、4.1.5
、4.2.0
、4.2.1
内存溢出解决方案
通过修改mule4
的元空间内存分配,可以缓解这个问题。可以在servers/conf
中修改配置/包装器配置文件。
建议的配置是:
# Limit the Metaspace Size to protect system memory from unwanted usage
# Increase this value if you get "Java.lang.OutOfMemoryError: Metaspace" error
wrapper.java.additional.7=-XX:MetaspaceSize=128m
wrapper.java.additional.8=-XX:MaxMetaspaceSize=256m
除了这里所描述的之外,还有一些场景会耗尽Java的元空间内存,这仅仅是因为应用程序需要256MB以上。您可以在遇到此问题的第一个实例中增加MaxMetaspaceSize
,以放弃实际具有较低的最大值。不要增加MetaspaceSize
的值。
JDK8 Metaspace OutOfMemory问题
我们正在开发一个业务应用程序(100万以上的LOC)已经有10多年的历史了。当切换到JDK8时,我们遇到了JDK8的元空间问题。这似乎与中引用的JaxB版本有关com.sun.xml.ws:webservices rt:1.4(Metro 1.4)
。由于应用程序中的紧密链接以及通过JaxB遗留的类/实例创建,动态切换旧库并不简单。
目前我们正在研究这个问题。我们创建了一个复制此行为的示例程序:
import java.io.ByteArrayInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class X
{
private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><x test=\"test\" />";
@XmlAttribute
String test;
public static void main( String[] args ) throws JAXBException, InterruptedException
{
System.out.println("start");
while ( true )
{
JAXBContext jc = JAXBContext.newInstance( X.class );
Unmarshaller unmarshaller = jc.createUnmarshaller();
X object = (X) unmarshaller.unmarshal( new ByteArrayInputStream( XML.getBytes() ) );
System.out.println( object.test );
}
}
}
JDK7保持PermGenSpace永久空间的clean。(16M PermGen
模拟)JDK7运行内存
使用JDK8,应用程序运行缓慢,出现OOM异常。VisualVM捕获异常并使进程在最大可用元空间上运行。即使在这里,它在运行JDK8的max(用16M元空间模拟)内存上运行了相当长一段时间后,它仍然会受到阻碍
运行参数JDK7:
-XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:MaxPermSize=16M -XX:PermSize=1M -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError
运行参数JDK8:
-XX:+TraceClassLoading -XX:+TraceClassUnloading -XX:MaxMetaspaceSize=16M -XX:MetaspaceSize=1M -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError
我们通过使用以下VM参数解决了metaspace 内存溢出的问题,直到能够修复应用程序中发生的所有问题:
-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true
我希望这将有助于其他类似metaspace oom的问题解决。
Gary的解决方案,它比仅仅设置一个标志要好(因为甚至JAXB的人也建议将其设为singleton
…)
private static Map<class<?>, JAXBContext> contextStore = new ConcurrentHashMap<class<?>, JAXBContext>();
...
protected static JAXBContext getContextInstance(Class<?> objectClass) throws JAXBException{
JAXBContext context = contextStore.get(objectClass);
if (context==null){
context = JAXBContext.newInstance(objectClass);
contextStore.put(objectClass, context);
}
return context;
}
//using it like this:
JAXBContext context = getContextInstance(objectClass);
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/795.html
暂无评论