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元素怎么取消事件
关于原生JS元素怎么取消事件,有3种方式 常规方法:removeEventListener 案例: <body> <div id="myDIV"> div ...
- git bash命令行使用https协议方式进行克隆和提交到github服务器
在本地创建一个文件夹来存放远程服务器仓库:如创建一个git8文件夹: 在命令行中,使用git clone https://github.com/serverking/weixin.git进行克隆git ...
- proxifier配合ss,实现全局代理
proxfixer配合ss的话,基本可以实现全局代理,分应用代理,或者玩外服的游戏(一般的游戏默认不走代理,本软件可以强制应用代理) 由于ss使用的是sockets5代理,一般情况下只有浏览 ...
- ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及abp封装的Javascript函数库
经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这里算是前面几节的一个初次试水. 首先我们数据库已经有的相应的数据. 模型和DTO已经建好,所以我们直接在服务 ...
- java编写双色球源代码。-----系统作为彩票双色球生成器,模拟机选一注双色球的彩票号码
package demo2; import java.util.Arrays; import java.util.Random; /** * 系统作为彩票双色球生成器,模拟机选一注双色球的彩票号码: ...
- MapReduce最大值
package com.bw.hadoop;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import ...
- css小随笔
一.什么是CSS W3C标准中,倡导有3:其一为内容与表现分离,其二为内容与行为分离,其三为内容结构的语义化.其倡导中第一条的"表现"指的便可以说是CSS.CSS全称Cascadi ...
- 重构tableview!
昨天用字典构筑tableview简直愚蠢!不过蠢过才知道如何写出好的代码.下面将用模型重构tableview! -------------------------------------------- ...
- PhantomJS 与python的结合
待完善 一.简介 PhantomJS是一个基于webkit的JavaScript API.它使用QtWebKit作为它核心浏览器的功能,使用webkit来编译解释执行JavaScript代码.任何你可 ...
- U3D操作游戏对象
游戏对象:所有出现在场景中的实体都是游戏对象. 一.创建游戏对象 创建游戏对象有两种方式:一是通过在unity中创建模型,而是通过脚本动态创建游戏对象.通过脚本动态创建的灵活性较高,重点也在于通过脚本 ...