4年前 (2020-11-11)  jvm |   抢沙发  1427 
文章评分 0 次,平均分 0.0

java.lang.OutOfMemoryError

由于内存泄漏,应用程序可能无法使用java.lang.OutOfMemoryError:Metaspace 元空间异常

Java metaspace outofmemory

已知在以下情况下会发生此问题:

  1. 应用程序的部署
  2. 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.44.1.54.2.04.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

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册