java8 去掉 perm 用 Metaspace 来替代
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt266
正如大家所知,JDK 8 Early Access版已经提供下载。这使开发者可以体验Java8的新特性。其中之一,是Oracle从JDK7发布以来就一直宣称的要完全移除永久代空间。例如,字符串内部池,已经在JDK7中从永久代中移除。JDK8的发布将宣告它的终结。这篇文章将会分享到目前为止对 PermGen 继任者:Metaspace的了解。我们将通过运行一个存在类元数据对象“泄漏”的程序,来对比HotSpot1.7与HotSpot1.8(b75,译者注:翻译文章时已经到b118)的运行时行为。待Java 8 正式发布之后,才会提供最终的规范,优化参数和相关文档。
元空间(Metaspace):
一种新的内存空间的诞生
JDK8 HotSpot JVM 使用本地内存来存储类元数据信息并称之为:元空间(Metaspace);这与Oracle JRockit 和IBM JVM’s很相似。这将是一个好消息:意味着不会再有java.lang.OutOfMemoryError: PermGen问题,也不再需要你进行调优及监控内存空间的使用……但请等等,这么说还为时过早。在默认情况下,这些改变是透明的,接下来我们的展示将使你知道仍然要关注类元数据内存的占用。请一定要牢记,这个新特性也不能神奇地消除类和类加载器导致的内存泄漏。你需求使用不同的方法以及遵守新的命名约定来追踪这些问题。我推荐大家阅读有关PermGen移除总结和Jon对此的评论。
总结如下:
PermGen 空间的状况
这部分内存空间将全部移除。
JVM的参数:PermSize 和 MaxPermSize 会被忽略并给出警告(如果在启用时设置了这两个参数)。
Metaspace 内存分配模型
大部分类元数据都在本地内存中分配。
用于描述类元数据的“klasses”已经被移除。
Metaspace 容量
默认情况下,类元数据只受可用的本地内存限制(容量取决于是32位或是64位操作系统的可用虚拟内存大小)。
新参数(MaxMetaspaceSize)用于限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整。
Metaspace 垃圾回收
对于僵死的类及类加载器的垃圾回收将在元数据使用达到“MaxMetaspaceSize”参数的设定值时进行。
适时地监控和调整元空间对于减小垃圾回收频率和减少延时是很有必要的。持续的元空间垃圾回收说明,可能存在类、类加载器导致的内存泄漏或是大小设置不合适。
Java 堆内存的影响
一些杂项数据已经移到Java堆空间中。升级到JDK8之后,会发现Java堆 空间有所增长。
Metaspace 监控
元空间的使用情况可以从HotSpot1.8的详细GC日志输出中得到。
Jstat 和 JVisualVM两个工具,在我们使用b75版本进行测试时,已经更新了,但是还是能看到老的PermGen空间的出现。
前面已经从理论上充分说明,下面让我们通过“泄漏”程序进行新内存空间的观察……
PermGen vs. Metaspace 运行时比较
为了更好地理解Metaspace内存空间的运行时行为,我们建立了一个类元数据泄漏程序。可以从此处下载源代码。
将进行以下几种场景的测试:
使用JDK1.7运行Java程序,监控并耗尽设定的128MB大小的PermGen内存空间。
使用JDK1.8 (b75)运行Java程序,监控新Metaspace内存空间的动态增长和垃圾回收过程。
使用JDK1.8 (b75)运行Java程序,模拟耗尽通过“MaxMetaspaceSize”参数设定的128MB大小的Metaspace内存空间。
JDK 1.7 @64-bit – PermGen 耗尽测试
Java程序中包括5万次可配置迭代过程
Java堆大小为1024 MB
Java的PermGen空间为128 MB(-XX:MaxPermSize=128m)
可以从上面的JVisualVM的截图看出:当加载超过3万个类之后,PermGen被耗尽。我们也能通过程序和GC的输出观察耗尽的过程。
copy
Class metadata leak simulator
Author: Pierre-Hugues Charbonneau
http://javaeesupportpatterns.blogspot.com
ERROR: java.lang.OutOfMemoryError: PermGen space
下面我们使用HotSpot JDK 1.8 JRE来执行程序。
JDK 1.8 @64-bit – Metaspace大小动态调整测试
Java程序中包括5万次可配置迭代过程
Java堆大小为1024 MB
Java的Metaspace空间:不受限制 (默认)
从上面的截图可以看到详细的GC输出日志,JVM Metaspace进行了动态扩展,本地内存的使用由20MB增长到328MB,以满足程序中不断增长的类数据内存占用需求。我们也能观察到JVM的垃圾回收事件—试图销毁僵死的类或类加载器对象。但是,由于我们程序的泄漏,JVM别无选择只能动态扩展Metaspace内存空间。程序能够运行5万次迭代,加载超过5万个类,而没有出现OOM事件。下面继续进行最后的一个测试场景:
JDK 1.8 @64-bit – Metaspace depletion
Java程序中包括5万次可配置迭代过程
Java堆大小为1024 MB
Java的Metaspace空间:128MB(-XX:MaxMetaspaceSize=128m)
可以从上面的JVisualVM的截图看出:当加载超过3万个类之后,Metaspace被耗尽;与JDK1.7运行时非常相似。我们也能通过程序和GC的输出观察耗尽的过程。另一个有趣的现象是,保留的原生内存占用量是设定的最大大小两倍之多。这可能表明,如果可能的话,可微调元空间容量大小策略,来避免本地内存的浪费。
从Java程序的输出中看到如下异常。
[html] view plaincopy
Class metadata leak simulator
Author: Pierre-Hugues Charbonneau
http://javaeesupportpatterns.blogspot.com
ERROR: java.lang.OutOfMemoryError: Metadata space
完成!
正如预期的那样,像运行JDK1.7基线时一样,限定128 MB大小元空间时,并不能让程序完成50万次迭代。一种新的OOM错误被JVM抛出。上述OOM事件,是由于元空间内存分配失败由JVM抛出的。
#metaspace.cpp
结束语
我希望您能喜欢这篇较早的对Java8元空间的分析和实验文章。目前的观察有力地表明,适当的监控和调优是必须的,以此来避免诸如,过度的在元空间中的GC,或像我们测试场景下触发OOM的条件。后面的文章中可能包括,性能上的比较,以确定这一新特性是否有潜在的性能上的提升。
参考:Java 8: From PermGen to Metaspace from ourJCG partner Pierre-Hugues Charbonneau at theJava EE Support Patterns & Java Tutorialblog.
java8 去掉 perm 用 Metaspace 来替代的更多相关文章
- Metaspace 之一--java8 去掉 perm 用 Metaspace 来替代
正如大家所知,JDK 8 Early Access版已经提供下载.这使开发者可以体验Java8的新特性.其中之一,是Oracle从JDK7发布以来就一直宣称的要完全移除永久代空间.例如,字符串内部池, ...
- Java8 Lambda使用指南
Java8 Lambda 的使用指南 原文地址:https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#s ...
- metaspace之三--Metaspace解密
概述 metaspace,顾名思义,元数据空间,专门用来存元数据的,它是jdk8里特有的数据结构用来替代perm,这块空间很有自己的特点,前段时间公司这块的问题太多了,主要是因为升级了中间件所致,看到 ...
- Java.lang.OutOfMemoryError:Metaspace
Understand the OutOfMemoryError Exceptionhttps://docs.oracle.com/javase/8/docs/technotes/guides/trou ...
- JVM(完成度95%,不断更新)
一.HotSpot HotSpot是最新的虚拟机,替代了JIT,提高Java的运行性能.Java原先是将源代码编译为字节码在虚拟机运行,HotSpot将常用的部分代码编译为本地代码. 对象创建过程 类 ...
- 【垃圾回收】Java内存回收实践经验 防止内存报警
jdk6和7服务器端(-server) 默认的新生代的垃圾回收器为:PS Scavenge,老年代默认的垃圾回收器为:PS MarkSweep 目前项目使用了jdk7,tomcat7,经常出现内存堆使 ...
- jdk8 永久代变更
java8 去掉了永久代permgen(又称非堆,其实也是堆的一部分),类的方法代码,常亮,方法名,静态变量等存放在永久代中 改为使用元空间 Metaspace , Metaspace 不在是堆的一部 ...
- HotSpot Java虚拟机中的“方法区”“持久代”“元数据区”的关系?
Sun/Oracle JDK的HotSpot VM中,直到JDK7都有“持久代”(Permanent Generation,简称PermGen).也称为方法区.Oracle JDK8的HotSpot ...
- 深入理解JVM虚拟机11:Java内存异常原理与实践
本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...
随机推荐
- js 重载(overload)
1.js中不支持重载的语法.(因为js不允许多个同名函数存在) 解决:使用arguments类数组对象接收调用时所有传入的参数值. 2. arguments可以使用length属性,通过下标访问,不能 ...
- Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
我用String代替了链表显示,本题的大意是每k个进行逆序处理,剩下的不够k个的就按照原顺序保留下来. public class ReverseNodes { public static void m ...
- Head First 设计模式 第6章 命令模式
第6章 命令模式 在本章,我们将把封装带到一个全新的境界,把方法调用封装起来.没错,通过方法调用,我们可以把运算块包装成型.所以,调用此运算的对象不需要关心运算是如何进行的,只要知道如何使用包装成型的 ...
- go的变量redeclare的问题,golang的一个小坑
go的变量声明有几种方式: 1 通过关键字 var 进行声明 例如:var i int 然后进行赋值操作 i = 5 2 最简单的,通过符号 := 进行声明和赋值 例如: i:=5 golang会 ...
- 1.怎样控制div中的图片居中
答案如下: #div{ width: 100%; height: 100%; border: 1px solid #000; text-align: center;}#div img{ vertica ...
- 曲线点抽稀算法-Python实现
何为抽稀 在处理矢量化数据时,记录中往往会有很多重复数据,对进一步数据处理带来诸多不便.多余的数据一方面浪费了较多的存储空间,另一方面造成所要表达的图形不光滑或不符合标准.因此要通过某种规则,在保证矢 ...
- ExtJs 思维导图
搭建环境: 1. 建tomcat , eclipse2. 复制 Extjs 到 项目的 webcontent下 (建议用自己一个熟悉的Extjs版本,我用Ext JS 4.2), 备份一个ext目录, ...
- Struts2传参碰到的奇怪问题
在使用Struts2框架,前端页面提交参数为日期时,Action中获取类型直接是Date 出现的问题是,局域网中无法访问,外网可正常访问. 把Action中Date类型换成String类型都可正常访问 ...
- CSS层级关系
http://www.blogbus.com/eskimo-logs/69626018.htmlhttp://www.dmtuan.com/?p=574
- IT类非开发面试总结--2
面试总结.. ================================= 第一部分..(自己对公司的最低要求) 面试需要提前准备的是:<想好自己以后要干嘛--我在想我以后要干嘛> ...