JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)
1.背景
2.为什么废弃永久代(PermGen)
3.深入理解元空间(Metaspace)
4.总结
========正文分割线=====
一、背景
1.1 永久代(PermGen)在哪里?
根据,hotspot jvm结构如下(虚拟机栈和本地方法栈合一起了):

上图引自网络,但有个问题:方法区和heap堆都是线程共享的内存区域。
关于方法区和永久代:
在HotSpot JVM中,这次讨论的永久代,就是上图的方法区(JVM规范中称为方法区)。《Java虚拟机规范》只是规定了有方法区这么个概念和它的作用,并没有规定如何去实现它。在其他JVM上不存在永久代。
1.2 JDK8永久代的废弃
JDK8 永久代变化如下图:

1.新生代:Eden+From Survivor+To Survivor
2.老年代:OldGen
3.永久代(方法区的实现) : PermGen----->替换为Metaspace(本地内存中)
二、为什么废弃永久代(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.测试字符串常量

1 public class StringOomMock {
2 static String base = "string";
3
4 public static void main(String[] args) {
5 List<String> list = new ArrayList<String>();
6 for (int i=0;i< Integer.MAX_VALUE;i++){
7 String str = base + base;
8 base = str;
9 list.add(str.intern());
10 }
11 }
12 }

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

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

可见在jdk8中:
1.字符串常量由永久代转移到堆中。
2.持久代已不存在,PermSize MaxPermSize参数已移除。(看图中最后两行)
3.3.2.测试元空间溢出
根据定义,我们以加载类来测试元空间溢出,代码如下:

1 package jdk8;
2
3 import java.io.File;
4 import java.lang.management.ClassLoadingMXBean;
5 import java.lang.management.ManagementFactory;
6 import java.net.URL;
7 import java.net.URLClassLoader;
8 import java.util.ArrayList;
9 import java.util.List;
10
11 /**
12 *
13 * @ClassName:OOMTest
14 * @Description:模拟类加载溢出(元空间oom)
15 * @author diandian.zhang
16 * @date 2017年4月27日上午9:45:40
17 */
18 public class OOMTest {
19 public static void main(String[] args) {
20 try {
21 //准备url
22 URL url = new File("D:/58workplace/11study/src/main/java/jdk8").toURI().toURL();
23 URL[] urls = {url};
24 //获取有关类型加载的JMX接口
25 ClassLoadingMXBean loadingBean = ManagementFactory.getClassLoadingMXBean();
26 //用于缓存类加载器
27 List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
28 while (true) {
29 //加载类型并缓存类加载器实例
30 ClassLoader classLoader = new URLClassLoader(urls);
31 classLoaders.add(classLoader);
32 classLoader.loadClass("ClassA");
33 //显示数量信息(共加载过的类型数目,当前还有效的类型数目,已经被卸载的类型数目)
34 System.out.println("total: " + loadingBean.getTotalLoadedClassCount());
35 System.out.println("active: " + loadingBean.getLoadedClassCount());
36 System.out.println("unloaded: " + loadingBean.getUnloadedClassCount());
37 }
38 } catch (Exception e) {
39 e.printStackTrace();
40 }
41 }
42 }

为了快速溢出,设置参数:-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m,运行结果如下:

上图证实了,我们的JDK8中类加载(方法区的功能)已经不在永久代PerGem中了,而是Metaspace中。可以配合JVisualVM来看,更直观一些。
四、总结
本文讲解了元空间(Metaspace)的由来和本质,常用配置,以及监控测试。元空间的大小是动态变更的,但不是无限大的,最好也时常关注一下大小,以免影响服务器内存。
JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)的更多相关文章
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)
Java8内存模型—永久代(PermGen)和元空间(Metaspace) 查看原文点击传送门:http://www.cnblogs.com/paddix/p/5309550.html 提示:本文做了 ...
- (转)Java8内存模型—永久代(PermGen)和元空间(Metaspace)
背景:介绍java8中永久代到元空间的转变. Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法 ...
- 转:Java8内存模型—永久代(PermGen)和元空间(Metaspace)
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...
- Java8内存结构—永久代(PermGen)和元空间(Metaspace)
本文转载 作者:liuxiaopeng 博客地址:https://www.cnblogs.com/paddix/p/5309550.html 一.JVM 内存结构 根据 JVM 规范,JVM 内存共分 ...
- java 8中撤销永久代,引入元空间
撤销永久代,引入元空间: 在 JDK 1.8 中,HotSpot 已经没有 “PermGen space”这个空间了,取而代之是一个叫做 Metaspace(元空间) 的东西. Java7中已经将字符 ...
- JVM虚拟机21: 1.8中废弃永久代(PermGen)迎来元空间(Metaspace)
1.JDK8永久代的废弃 JDK8 永久代变化如下图: 1.新生代:Eden+From Survivor+To Survivor 2.老年代:OldGen 3.永久代(方法区的实现) : PermGe ...
- 深入理解java虚拟机---JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)(十二)
引用:https://www.cnblogs.com/yulei126/p/6777323.html JDK8-废弃永久代(PermGen)迎来元空间(Metaspace) 1.背景 2.为什么废 ...
- jdk源码剖析五:JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)
目录 1.背景 2.为什么废弃永久代(PermGen) 3.深入理解元空间(Metaspace) 4.总结 ========正文分割线===== 一.背景 1.1 永久代(PermGen)在哪里? 根 ...
随机推荐
- Eclipse配置Tomcat服务器
Eclipse配置Tomcat服务器.. ---------------- ---------------- ---------------- ---------------- ----------- ...
- [js高手之路]设计模式系列课程-发布者,订阅者重构购物车
发布者订阅者模式,是一种很常见的模式,比如: 一.买卖房子 生活中的买房,卖房,中介就构成了一个发布订阅者模式,买房的人,一般需要的是房源,价格,使用面积等信息,他充当了订阅者的角色 中介拿到卖主的房 ...
- myeclipse db browser 新建数据源
Myeclipse 新建数据源 一.打开myeclipse(打开了当我没说) 二.在window选项中找到show view ,点击other,输入db,选择DB Browser 三.在DB Brow ...
- 转每天一个linux命令(2):cd命令
Linux cd 命令可以说是Linux中最基本的命令语句,其他的命令语句要进行操作,都是建立在使用 cd 命令上的. 所以,学习Linux 常用命令,首先就要学好 cd 命令的使用方法技巧. 1 ...
- switch处理多分支结构
import java.util.Scanner; /** * Created by liwenj on 2017/7/17. */ public class test9 { public stati ...
- 网上搜索到的 比较好的mysql查询语句练习题
Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...
- 中科微北斗定位模组ATGM336H简介
36H系列卫星定位模块 产品介绍 ATGM336H是高灵敏度,支持BDS/GPS/GLONASS卫星导航系统的单系统定位,以及任意组合的多系统联合定位的接收机模块.ATGM336H基于本公司自主独立研 ...
- Angular中Constructor 和 ngOnInit 的本质区别
在Medium看到一篇Angular的文章,深入对比了 Constructor 和 ngOnInit 的不同,受益匪浅,于是搬过来让更多的前端小伙伴看到,翻译不得当之处还请斧正. 本文出处:The e ...
- chrome开发工具指南(九)
检查和管理存储.数据库与缓存 查看和修改本地存储与会话存储. 检查和修改 IndexedDB 数据库. 对 Web SQL 数据库执行语句. 查看应用缓存和服务工作线程缓存. 点击一次按钮即可清除所有 ...
- poj 1149经典网络流构图
题意:m个猪圈,n个客户,每个客户给出选则猪圈的钥匙和需要购买猪的个数,其中每次客户购买时客户选则的猪圈数量可以相互更换,问最大购买数量. 思路:以客户作为除源点汇点之外的点,然后对于每个猪圈从源点连 ...