JAVA 8 :从永久区(PermGen)到元空间(Metaspace)
你注意到了吗?JDK 8早期可访问版本已经提供下载了,java 开发人员可以使用java 8 提供的新的语言和运行特性来做一些实验。其中一个特性就是完全的移除永久代(Permanent Generation (PermGen)),这从JDK 7开始Oracle就开始行动了,比如:本地化的String从JDK 7开始就被移除了永久代(Permanent Generation )。JDK 8让它最终退役了。
本文将会分享至今为至我收集的关于永久代(Permanent Generation )的替代者:元空间(Metaspace)的信息。我也会比较在执行JAVA 程序时HotSpot 1.7 和 HotSpot 1.8 (b75)的运行行为。
关于元空间(Metaspace)最后的规范、调整参数和文档将在Java 8 正式发布之后公开。
元空间(Metaspace):一个新的内存空间的诞生
与 Oracle JRockit 和 IBM JVM类似,JDK 8.HotSpot JVM开始使用本地化的内存存放类的元数据,这个空间叫做元空间(Metaspace)。
一 个好的消息是意味着java.lang.OutOfMemoryError: PermGen的空间问题将不复存在,并且不再需要调整和监控这个内存空间,虽然还没有那么快。当这个变化被默认执行的时候,我们会发现你任然需要担心类的元数据的内存占用率的问题,所以请记住这个新的特性并不会奇迹般的消除类和类加载器的内存泄漏。而是你需要使用一些不同的方式和学习新名词来追查这些问题。
我建议你阅读永久带移除的总结和Jon对这个问题的意见。
总结:
永久区的情况:
这个内存空间被完全的移除
JVM参数PermSize 和 MaxPermSize会被忽略,当前在启动时会有警告信息
元空间(Metaspace)内存分配模型
现在大多数的类元数据分配在本地化内存中。
我们用来描述类的元数据的klasses已经被移除。
元空间的容量
默认情况下,类元数据分配受到可用的本机内存容量的限制(容量依然取决于你使用32位JVM还是64位操作系统的虚拟内存的可用性)。
一个新的参数 (MaxMetaspaceSize)可以使用。允许你来限制用于类元数据的本地内存。如果没有特别指定,元空间将会根据应用程序在运行时的需求动态设置大小。
元空间的垃圾回收
如果类元数据的空间占用达到参数“MaxMetaspaceSize”设置的值,将会触发对死亡对象和类加载器的垃圾回收。
为了限制垃圾回收的频率和延迟,适当的监控和调优元空间是非常有必要的。元空间过多的垃圾收集可能表示类,类加载器内存泄漏或对你的应用程序来说空间太小了。
java堆空间的影响
一些各种各样的数据已经转移到Java堆空间。这意味着未来的JDK8升级后,您可能会发现Java堆空间的不断增加。
元空间监控
元空间的使用从HotSpot 1.8开始有详细的GC日志输出。
在我们基于B75测试的时候Jstat 和JVisualVM还没有升级, 目前还是引用到老的永久代空间。现在有足够的理论,我们可以通过我们的Java程序泄漏的行为来观察我们的这个新的内存空间...
永久代和元空间运行时对照
为了更好的理解新的元空间运行时的行为特征,我们创建一个类元数据泄露的java程序,你可以在这里下载源代码:
我们测试下面的场景:
使用JDK 1.7运行java程序,并且为了监控和耗尽永久代内存空间,将其设置为128MB
使用JDK1.8(B75)运行java程序,并且监控新的元空间内存的冬天增长和垃圾回收。
使用JDK1.8(B75)运行java程序,通过设置MaxMetaspaceSize 为128MB来同样耗尽元空间 .
JDK 1.7 @64-bit – PermGen depletion
java程序设置50k次的迭代
java的堆空间为1024MB
java的永久代空间为128MB (-XX:MaxPermSize=128m)
正如你看到的JVisualVM的报告,当加载30K+ 的类的时候,永久代被耗尽。我们也可以从程序和GC的输出文件中发现耗尽。类元数据泄漏模拟器的作者Pierre-Hugues Charbonneau在博客: http://javaeesupportpatterns.blogspot.com中描述了错误: ERROR: java.lang.OutOfMemoryError: PermGen space 。现在我们使用 HotSpot JDK 1.8 JRE.来运行程序。
JDK 1.8 @64-bit – Metaspace dynamic re-size
Java 程序设置50k次的迭代
Java 堆空间为1024MB
Java 元空间为无限(默认值)
正如你看到的详细的GC输出,为了满足我们的Java程序不断增加的类元数据的内存占用,JVM元空间扩大从20 MB动态占用本机内存高达328 MB。我们也可以观察垃圾收集,JVM在试图摧毁任何死类或类加载器对象。自从我们的Java程序泄漏,JVM不得不扩张元空间的内存空间。
该方案可以迭代50K次,并且没有OOM事件和加载50K+类。
接下去我们来看最后的测试场景:
JDK 1.8 @64-bit – Metaspace depletion
Java 程序设置50k次的迭代
Java 堆空间为1024MB
Java 元空间为128 MB (-XX:MaxMetaspaceSize=128m)
正如你看到的JVisualVM的报告,当加载30K+ 的类的时候,元空间被耗尽,和在JDK1.7的表现非常相近。我们也可以在程序和GC的输出日志中找到。另一个有趣的现象是,本机内存保留的占用空间是指定的最大大小的两倍之多。如果可能的话,为了避免本机内存浪费。这可能表明需要优化元空间扩张尺寸的策略,。
现在我们可以从java程序的输出日志中找到下面的异常:
view sourceprint?
1.
Class metadata leak simulator
2.
Author: Pierre-Hugues Charbonneau
3.
http://javaeesupportpatterns.blogspot.com
4.
ERROR: java.lang.OutOfMemoryError: Metadata space
5.
Done!
正如预期的那样,设置元空间最大尺寸为128 MB,就像我们在JDK1.7中一样没有让我们完成我们的50K迭代的计划。JVM抛出一个新的OOM错误。上述OOM事件是由JVM从元空间在捕获一个一个内存分配失败后抛出。
#metaspace.cpp 结束语
我希望你能欣赏这个对新的Java8元空间的早期的分析和实验 。目前观测表明,为了远离类似在我们最后测试场景中出现的频繁的元空间GC和OOM的问题,适当的监控和调优是必须的。以后的文章中可能包括性能比较,以确定这一新功能相关的潜在性能改进。请随时提供任何意见。
JAVA 8 :从永久区(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体系结构之七:持久代、元空间(Metaspace) 常量池==了解String类的intern()方法、常量池介绍、常量池从Perm-->Heap
一.intern()定义及使用 相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: public native String inter ...
- JVM元空间(Metaspace)
本文转载自JVM学习--元空间(Metaspace) 从方法区(PermGen)到元空间(Metaspace) 方法区(PermGen) JDK1.8以前的HotSpot JVM有方法区,也叫永久代( ...
- 面试官,Java8 JVM内存结构变了,永久代到元空间
在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...
- JAVA8 JVM内存结构变了,永久代到元空间
在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...
随机推荐
- sqlplus无法登陆?
关键词:error 6 initialize sqlplus,ORA-27101: shared memory realm does not exist 1.error 6 initialize sq ...
- C++中的class和struct区别
1,经过不停的改进,结构体 struct 变得原来越不像它在 C 语言中的样子了: 1,struct 在 C 语言中仅为了定义一个变量的集合,仅此而已,不能定义函数: 2,struct 在 C++ 中 ...
- HDU 1864 最大报销额 0-1背包
HDU 1864 最大报销额 0-1背包 题意 现有一笔经费可以报销一定额度的发票.允许报销的发票类型包括买图书(A类).文具(B类).差旅(C类),要求每张发票的总额不得超过1000元,每张发票上, ...
- nginx下载安装和虚拟机的配置
一. Nginx下载安装 1.Nginx下载:nginx-1.13.0.tar.gz,下载到:/usr/local/software/ wget http://nginx.org/download/n ...
- 使用Docker部署Spring-Boot+Vue博客系统
在今年年初的时候,完成了自己的个Fame博客系统的实现,当时也做了一篇博文Spring-boot+Vue = Fame 写blog的一次小结作为记录和介绍.从完成实现到现在,也断断续续的根据实际的使用 ...
- mongodb启动报错,child process failed, exited with error number 1
error: child process failed, exited with error number 1 第一次安装mongodb,随后启动一般不会出现上面的错误,出现这种错误的原因一般是mon ...
- CentOS7.6中 KVM虚拟机内存、CPU调整
CentOS7.6中 KVM虚拟机内存.CPU调整 一.调小虚拟机内存 调小虚拟机内存可以动态实现,不用关机 1.查看当前内存大小 [root@heyong kvm]# virsh dominfo t ...
- Nginx 编译安装工程优化
1.减小 nginx 编译后的文件大小 在编译 nginx 时,默认以 debug 模式进行,在 debug 模式下会插入很多跟踪和 assert 之类的信息. 在 nginx 源码文件解压后,找到源 ...
- Shell编程变量
shell变量 什么是变量,存放了各种数据,在linux怎么定义了变量,name=ken,name就是变量名,ken就是变量值, 但是在shell中,有三种方式: name=ken name='ken ...
- 2019 计蒜之道 复赛 D. “星云系统”(单调栈)
VIPKID 是在线少儿英语教育平台,网络稳定是在线教育课程质量的红线,VIPKID 为此推出了全球最稳定的教育网络系统 -- "星云系统".星云系统目前建立了覆盖全球 3535 ...