JVM深入:JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)(转)
转载自:https://www.cnblogs.com/yulei126/p/6777323.html
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)的由来和本质,常用配置,以及监控测试。元空间的大小是动态变更的,但不是无限大的,最好也时常关注一下大小,以免影响服务器内存。
JVM深入: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)在哪里? 根 ...
随机推荐
- Oracle内存详解之 Library cache 库缓冲
Oracle内存详解之 Library cache 库缓冲 2017年11月09日 11:38:39 阅读数:410更多 个人分类: 体系结构 Library cache是Shared pool的一部 ...
- Xcode注释快捷键和Alfred 快捷键冲突解决方案
在Alfred 中的Features -> File Search ->Navigation ->Previous Path 中的快捷方式改掉就可以了
- linux软件管理
People who cannot find time for recreation are obliged sooner or later to find time for illness.腾不出时 ...
- Accumulation Degree
#include<cstdio> #include<cstring> #define INF 0x7fffffff using namespace std; ; inline ...
- xilinx和altera的fpga的不同之处!----如果不知道,你将为之付出代价! --转载
本人从2004年接触fpga开始,至今已经8年了.开发过altera的flex系列和cyclone3系列:开发过xilinx的vii和v5系列.下面谈谈本人对二者的一些不同,以便引起开发者对一些细节上 ...
- left join on and 与 left join on where的区别
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: 1. on条件是在生成临时 ...
- [转] Brook 搭建教程
https://www.jiongjun.cc/technology/500.html 在搭建 brook 代理之前,首先要求你要有一台国外 vps,关于国外 vps 选择,可以参考这篇:推荐几款国外 ...
- IDEA安装ini4idea插件
参见https://blog.csdn.net/lintianlin/article/details/80050309
- Servlet(九):web.xml文件和server.xml文件
Web.xml 文件使用总结:作用: 存储项目相关的配置信息,保护 Servlet.解耦一些数据对程序的依赖.使用位置: 每个 Web 项目中Tomcat 服务器中(在服务器目录 conf 目录中)区 ...
- macOS上实现Qt应用程序做文件关联打开
一.背景介绍 用Qt开发的应用程序要实现文件关联,双击时用默认关联的程序打开文件,在Windows上这个功能非常容易实现.Windows应用程序在安装的时候可以在注册表中写入相关的键值对.打开文件的时 ...