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

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

内容简介: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

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


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

查看所有标签

猜你喜欢:

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

About Face 3

About Face 3

Alan Cooper、Robert Reimann、David Cronin / John Wiley & Sons / 2007-5-15 / GBP 28.99

* The return of the authoritative bestseller includes all new content relevant to the popularization of how About Face maintains its relevance to new Web technologies such as AJAX and mobile platforms......一起来看看 《About Face 3》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具