一、为什么废弃永久代(PermGen)
2.1 官方说明

参照JEP122:http://openjdk.java.net/jeps/122,原文截取:

Motivation

This is part of the JRockit and Hotspot convergence effort. JRockit customers do not need to configure the permanent generation (since JRockit does not have a permanent generation) and are accustomed to not configuring the permanent generation.
即:移除永久代是为融合HotSpot JVM与 JRockit VM而做出的努力,因为JRockit没有永久代,不需要配置永久代。

2.2 现实使用中易出问题

由于永久代内存经常不够用或发生内存泄露,爆出异常java.lang.OutOfMemoryError: PermGen

二、深入理解元空间(Metaspace)3.1元空间的内存大小

元空间是方法区的在HotSpot jvm 中的实现,方法区主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上属于堆的一部分,但是为了与堆进行区分,通常又叫“非堆”。
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。,理论上取决于32位/64位系统可虚拟的内存大小。可见也不是无限制的,需要配置参数。

3.2常用配置参数

1.MetaspaceSize
初始化的Metaspace大小,控制元空间发生GC的阈值。GC后,动态增加或降低MetaspaceSize。在默认情况下,这个值大小根据不同的平台在12M到20M浮动。使用Java -XX:+PrintFlagsInitial命令查看本机的初始化参数
2.MaxMetaspaceSize
限制Metaspace增长的上限,防止因为某些情况导致Metaspace无限的使用本地内存,影响到其他程序。在本机上该参数的默认值为4294967295B(大约4096MB)。
3.MinMetaspaceFreeRatio
当进行过Metaspace GC之后,会计算当前Metaspace的空闲空间比,如果空闲比小于这个参数(即实际非空闲占比过大,内存不够用),那么虚拟机将增长Metaspace的大小。默认值为40,也就是40%。设置该参数可以控制Metaspace的增长的速度,太小的值会导致Metaspace增长的缓慢,Metaspace的使用逐渐趋于饱和,可能会影响之后类的加载。而太大的值会导致Metaspace增长的过快,浪费内存。
4.MaxMetasaceFreeRatio
当进行过Metaspace GC之后, 会计算当前Metaspace的空闲空间比,如果空闲比大于这个参数,那么虚拟机会释放Metaspace的部分空间。默认值为70,也就是70%。
5.MaxMetaspaceExpansion
Metaspace增长时的最大幅度。在本机上该参数的默认值为5452592B(大约为5MB)。
6.MinMetaspaceExpansion
Metaspace增长时的最小幅度。在本机上该参数的默认值为340784B(大约330KB为)。

3.3测试并追踪元空间大小 3.3.1.测试字符串常量

 
 
public class StringOomMock {[/b]    static String  base = "string";
     
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        for (int i=0;i< Integer.MAX_VALUE;i++){
            String str = base + base;
            base = str;
            list.add(str.intern());
        }
    }
}

在eclipse中选中类--》run configuration-->java application--》new 参数如下:



由于设定了最大内存20M,很快就溢出,如下图:

可见在jdk8中:
1.字符串常量由永久代转移到堆中。
2.持久代已不存在,PermSize MaxPermSize参数已移除。(看图中最后两行)

3.3.2.测试元空间溢出

根据定义,我们以加载类来测试元空间溢出,代码如下:
 
package jdk8;
 
import java.io.File;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
 
/**
 *
 * @ClassName:OOMTest
 * @Description:模拟类加载溢出(元空间oom)
 * @author diandian.zhang
 * @date 2017年4月27日上午9:45:40
 */
public class OOMTest { 
    public static void main(String[] args) { 
        try
            //准备url 
            URL url = new File("D:/58workplace/11study/src/main/java/jdk8").toURI().toURL(); 
            URL[] urls = {url}; 
            //获取有关类型加载的JMX接口 
            ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean(); 
            //用于缓存类加载器 
            List<ClassLoader> classLoaders = new ArrayList<ClassLoader>(); 
            while (true) { 
                //加载类型并缓存类加载器实例 
                ClassLoader classLoader = new URLClassLoader(urls); 
                classLoaders.add(classLoader); 
                classLoader.loadClass("ClassA"); 
                //显示数量信息(共加载过的类型数目,当前还有效的类型数目,已经被卸载的类型数目) 
                System.out.println("total: " + loadingBean.getTotalLoadedClassCount()); 
                System.out.println("active: " + loadingBean.getLoadedClassCount()); 
                System.out.println("unloaded: " + loadingBean.getUnloadedClassCount()); 
            
        } catch (Exception e) { 
            e.printStackTrace(); 
        
    
}
为了快速溢出,设置参数:-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m,运行结果如下:

上图证实了,我们的JDK8中类加载(方法区的功能)已经不在永久代PerGem中了,而是Metaspace中。可以配合JVisualVM来看,更直观一些。

JVM补充一的更多相关文章

  1. JVM补充篇

    1.对象分配原则 1)对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC 2)大对象直接进入老年代(大对象是指需要大量连续内存空间的对象),这样做的目的是避免在E ...

  2. JVM 知识点补充——永久代和元空间

    之前已经讲过了不少有关 JVM 的内容,今天准备将之前没有细讲的部分进行补充,比如:永久代和元空间. 永久代 Java 的内存中有一块称之为方法区的部分,在 JDK8 之前, Hotspot 虚拟机中 ...

  3. JVM 专题五:类加载子系统(三)补充内容

    3. 补充内容 3.1 在jvm中表示两个class对象是否为同一个类的两个必要条件 类的完整类名必须一致,包括包名. 加载这个类的ClassLoader(指ClassLoader实例对象)必须相同 ...

  4. <JVM下篇:性能监控与调优篇>补充:使用OQL语言查询对象信息

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  5. <JVM下篇:性能监控与调优篇>补充:浅堆深堆与内存泄露

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  6. JVM学习第三天(JVM的执行子系统)之类加载机制补充

    昨晚没看完,今天继续 系统的类加载器 对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间.这句话可以表达得更通俗一些: ...

  7. JVM运行时数据区--纵向补充--对象的实例化内存布局与访问定位

    对象的实例化 创建对象的方式 1.new:最常见的方式(本质是构造器) 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 2.Class的newInsta ...

  8. 深入理解java虚拟机笔记补充-JVM常见参数设置

    JVM 常见参数设置 内存设置 参数 -Xms:初始堆大小,JVM 启动的时候,给定堆空间大小. -Xmx:最大堆大小,如果初始堆空间不足的时候,最大可以扩展到多少. -Xmn:设置年轻代大小.整个堆 ...

  9. JVM垃圾回收补充知识点

    1. 分代 虚拟机中的共划分为三个代: 年轻代(Young Gen):eden和survivor-8:1:1 年老代(Old Gen):存储大对象,由survivor晋升 永久代(perm Gen): ...

随机推荐

  1. get all sites under IIS

    https://stackoverflow.com/questions/2555668/how-to-programmatically-get-sites-list-and-virtual-dirs- ...

  2. Silverlight中使用MVVM(2)

    Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...

  3. 一步一步学Silverlight 2系列(29):使用Transform实现更炫的效果(上)

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  4. nyoj 999

    nyoj 999: 点击打开题目链接 题目思路,处理一下地图,把 D E 能看到的地方标记一下.然后就是暴力广搜一下.标记状态,因为同样在同一个点,但是你刚出发到达那点和找到D之后到达相同的点和找到E ...

  5. 移动前端开发之viewport的理解

    在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport了,只有明白了viewport的概念以及弄清楚了跟viewport有关的meta标签的使用,才能更好地让我们的网页适配或 ...

  6. I.MX6 不一定要设置BOOT_MODE进入烧录模式

    /************************************************************************* * I.MX6 不一定要设置BOOT_MODE进入 ...

  7. 「LuoguP1496」 火烧赤壁

    Description 曹操平定北方以后,公元208年,率领大军南下,进攻刘表.他的人马还没有到荆州,刘表已经病死.他的儿子刘琮听到曹军声势浩大,吓破了胆,先派人求降了. 孙权任命周瑜为都督,拨给他三 ...

  8. 读取每行的数据,加入到list中

    有txt文件中,每行都有一个字符串或者数据,将每行的数据转换到一个list中 例如: 1 2 3 6 实现: f = open("test1.txt",'r') list1 = [ ...

  9. k8s-helm-二十四

    一.介绍 Helm是Kubernetes的一个包管理工具,用来简化Kubernetes应用的部署和管理.可以把Helm比作CentOS的yum工具. yum不光要解决包之间的依赖关系,还要提供具体的程 ...

  10. iView 实战系列教程(21课时)_1.iView 实战教程之配置篇

    1.iView 实战教程之配置篇 点击添加插件,. 选中后安装 全部导入还是按需导入. 2.是否需要自定义主题变量 3.多语言的设置. 这里我们全部选择为默认 然后点击继续. 启动项目 入口文件导入了 ...