【深入浅出-VisualVM】(3):分析PermGenOOM

栏目: Java · 发布时间: 5年前

内容简介:PermGen Space是Oracle-Sun Hotspot才有的,同类产品Oralce JRockit, IBM J9, Taobao JVM 是没有的,在Java8中永久区(PermGen)已经变成元空间(Metaspace),这里怀旧一下。设置VM启动参数

PermGen Space是Oracle-Sun Hotspot才有的,同类产品Oralce JRockit, IBM J9, Taobao JVM 是没有的,在 Java 8中永久区(PermGen)已经变成元空间(Metaspace),这里怀旧一下。

【深入浅出-VisualVM】(3):分析PermGenOOM

案例:PermGen OOM

设置VM启动参数 -XX:PermSize=5m -XX:MaxPermSize=5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\dump 运行下面代码(这里用的Maven仓库下的jar包,根据自己情况来),通过不断的动态加载类(Spring经常干这样的事情),造成PermGen OOM. 一般JVM默认PermGen大约是80M左右(和环境也有点关系,不过八九不离十),可以通过 jmap -heap pid 查看,为什么那么小可以看下 这个回答

【深入浅出-VisualVM】(3):分析PermGenOOM 【深入浅出-VisualVM】(3):分析PermGenOOM

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
 
 
public class PermGen {
 
    private static List<Object> insList = new ArrayList<Object>();
 
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, MalformedURLException, InterruptedException {
        permLeak();
    }
 
    private static void permLeak() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, MalformedURLException, InterruptedException{
        for (int i = 0; i < 1000 ; i++) {
            URL[] urls = getURLS();
            URLClassLoader loader = new URLClassLoader(urls,null);
            Class<?> logfClass = Class.forName("org.apache.commons.logging.LogFactory",true,loader);
            Method getLog = logfClass.getMethod("getLog", String.class);
            Object result = getLog.invoke(logfClass, "TestPermGen");
            insList.add(result);
            System.out.println(i + " : " + result);
            Thread.sleep(100);
        }
    }
 
    private static URL[] getURLS() throws MalformedURLException{
        File libDir = new File("D:\\HHSZXA\\.m2\\repository\\commons-logging\\commons-logging\\1.1.1");
        File[] subFiles = libDir.listFiles();
        int count = subFiles.length;
        URL[] urls = new URL[count];
        for (int i = 0; i < count ; i++) {
            urls[i] = subFiles[i].toURI().toURL();
        }
        return urls;
    }
 
 
}

输出:

0 : org.apache.commons.logging.impl.Jdk14Logger@2babbba1
1 : org.apache.commons.logging.impl.Jdk14Logger@5d08e435
2 : org.apache.commons.logging.impl.Jdk14Logger@30d46b95
3 : org.apache.commons.logging.impl.Jdk14Logger@4ec4f498
4 : org.apache.commons.logging.impl.Jdk14Logger@7dbc345a
5 : org.apache.commons.logging.impl.Jdk14Logger@7ee361ad
6 : org.apache.commons.logging.impl.Jdk14Logger@7d94a8eb
java.lang.OutOfMemoryError: PermGen space
Dumping heap to d:\dump\java_pid3276.hprof ...
Heap dump file created [2648239 bytes in 0.016 secs]
Exception in thread "Reference Handler" Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at PermGen.permLeak(PermGen.java:25)
    at PermGen.main(PermGen.java:16)
Caused by: java.lang.OutOfMemoryError: PermGen space
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.apache.commons.logging.LogFactory.createFactory(LogFactory.java:1131)
    at org.apache.commons.logging.LogFactory$2.run(LogFactory.java:1065)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.commons.logging.LogFactory.newFactory(LogFactory.java:1062)
    at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:650)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:704)
    ... 6 more
java.lang.OutOfMemoryError: PermGen space
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:140)

通过控制台信息,可以初步判定是方法区OOM,原因是通过URLClassLoader类加载器加载某个动态类,这个动态类是由调用org.apache.commons.logging.LogFactory.getLog方法生成的,同时可以看到引起的错误的代码行数PermGen.java:25

首先看摘要

【深入浅出-VisualVM】(3):分析PermGenOOM

【深入浅出-VisualVM】(3):分析PermGenOOM

其中1131行代码,就是实例化某个类,这个类是什么,我们可以改变日志输出级别,或者直接打印。

【深入浅出-VisualVM】(3):分析PermGenOOM

【深入浅出-VisualVM】(3):分析PermGenOOM

一切真相大白,有兴趣更深入的童鞋,欢迎讨论。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

场景革命

场景革命

吴声 / 机械工业出版社 / 2015-7-1 / 59.00元

How-old如何引爆了朋友圈的全民脑洞狂欢? Uber是打车软件,还是入口? 为什么“自拍”会成为一个产业? 美团如何成为电影票房冠军的幕后推手? 商业进入了新物种时代,超级平台之后,PC时代以降,IoT(万物互联)崛起之时,到底什么是新的入口?一系列的颠覆使我们开始正视移动互联时代的品类创造方法,一场孕育已久的场景革命正在发生。 《场景革命:重构人与商业的连接》为......一起来看看 《场景革命》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具