Java 8: 从永久代(PermGen)到元空间(Metaspace)

2023-11-09

    正如大家所知,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 JRockitIBM 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的输出观察耗尽的过程。

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程序的输出中看到如下异常。

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 Tutorial blog.


    原文地址


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 8: 从永久代(PermGen)到元空间(Metaspace) 的相关文章

  • 如何使用 UnboundID LDAP SDK 获取 LDAP 中的 DN 和用户 ID

    当我唯一的参数是用户 ID 时 我试图获取用户的 DN 可能不止一个 我还使用 UnboundID LDap SDK 如您所见 public String getCustomerAdminDN String uid String resul
  • 如何从二维数组中仅打印单个列?

    我正在编写这个程序 我必须只打印二维数组的一列 而不是两者 for int i 0 i lt sjf length i for int j 0 j lt sjf i length j System out printf 5d 4s sjf
  • Java NIO Pipe 与 BlockingQueue

    我刚刚发现它只有一个 NIO 工具 即 Java NIO Pipe 它是为在线程之间传递数据而设计的 与通过队列 例如 ArrayBlockingQueue 传递的更传统的消息相比 使用此机制是否有任何优势 通常 将数据传递给另一个线程进行
  • 涉及数学的方法给出与计算器不同的答案

    我是java新手 所以请耐心等待 我试图从比赛总数中获得胜利的百分比 但我正在做的事情还很遥远 我获取百分比的方法如下 public double winPercentage int wins int total return wins t
  • 正则表达式查找两个字符之间的内部匹配

    环境 Java 我想匹配两个字符串之间的字符 这是一个例子 foo
  • 转换为 JSON 后保留 XMLGregorianCalendar 日期格式 - Jackson Lib

    我有一个对象 它有 2 个 XMLGregorianCalendar 对象 一个用于日期 另一个用于时间 我使用 Jackson 对象映射器将日期转换为 JSON 格式 转换前的日期为2014年2月10日 时间为11 15 00 转换为 J
  • 我在 Android Studio 中使用哪个版本的 JDK 有关系吗?

    I know I can choose the SDK location in Android Studio s Project Structure 我有两个问题 当我们已经使用Android SDK时 为什么还需要JDK 毕竟我们不是为
  • Java Swing 自定义形状(2D 图形)

    我需要绘制自定义形状 现在 当用户单击面板上的几个点时 我使用多边形创建一个形状 public void mouseClicked MouseEvent e polygon addPoint e getX e getY repaint 但我
  • 使用 Windows 锁定屏幕后删除 Kerberos 缓存票证

    无论如何 有没有办法阻止 Kerberos 缓存的票证在 Windows 进入锁定屏幕后被删除 首次登录 Windows 时 klist exe 显示 2 个缓存票证 但是 发生 Windows 锁屏事件后 klist exe 显示 0 个
  • Bean 属性不可读或具有无效的 getter 方法

    因此 我的任务是为注册表路由编写一个简单的 Web 应用程序 使用 Spring MVC 所以我有 路线 类 我想在其中保留起点 终点和中间点列表 但我不明白如何将值从 jsp 放入列表 例如使用 jstl 所以我决定解析一个字符串 pub
  • 如何用Java捕获音频数据

    我想访问我的麦克风用 Java 录制的音频数据 我该怎么做呢 我的目标是保存录制的音频数据并同时向用户播放 如果您不需要 JMF 中的任何附加功能 我会避免使用它 因为开发已经停止 最后一个版本是 2004 年 它与 Java 6 存在兼容
  • 在同一个容器但不同的耳朵中使用本地EJB

    我正在尝试在同一个 Glassfish 但不同的耳朵中使用本地 EJB 但是Glassfish找不到本地EJB或者无法消费 我读到了这个 根据 JavaEE 教程 Local bean 的客户端 必须在与其访问的企业 bean 相同的 JV
  • Java检测音频文件(mp3)

    我有这段代码可以读取 mp3 文件 import java io File import java io IOException import javax sound sampled AudioSystem import javax sou
  • 使用 JNDI 添加 LDAP 条目

    我正在尝试使用 JNDI 将条目添加到 LDAP 服务器 我可以成功地从 LDAP 服务器读取条目 但是当我尝试添加新条目时出现错误 我检查了各种方法但都失败了 private String getUserAttribs String se
  • 从 Apache Kafka 中的主题删除消息

    所以我是 Apache Kafka 的新手 我正在尝试创建一个简单的应用程序 以便我可以更好地理解 API 我知道这个问题在这里被问了很多 但是如何清除存储在主题上的消息 记录 我看到的大多数答案都说要更改消息保留时间或删除并重新创建主题
  • 解析XML文件以获取所有命名空间信息

    我希望能够从给定的 XML 文件中获取所有名称空间信息 例如 如果输入 XML 文件类似于
  • Android 调整图片大小

    我的图像存储在 SD 卡上 每个大小约为 4MB 我想调整每个的大小 而不是将其设置为 ImageView 但我不能使用BitmapFactory decodeFile path 因为异常 java lang OutOfMemoryErro
  • Spring MVC 和复选框

    我正在使用 Spring MVC 3 0 并且不能完全看到这个问题的所有部分 我的控制器将生成一个域对象列表 假设有一个简单的 User 对象 具有firstName lastName age 和role 属性 我想在表中输出该用户列表 每
  • java银行程序帐户ID不上去?

    每次创建银行帐户时 帐户 ID 都应增加 1 但每次我尝试提取 Id 时 我只会得到帐户 ID 为 0 任何建议 因为我完全按照我学习的书中的方式进行操作而且它仍然没有更新 帐户构造函数 public class BankAccount p
  • 寻找基于循环固定大小数组的双端队列

    我正在寻找一个Deque其具有以下特点 它有固定的大小 如果我在头 尾添加元素 则另一端的元素会丢失 它是基于数组的 所以我可以在恒定时间内访问随机元素 我可以在前面或末尾添加元素 双端队列 我检查了Deque的实施JCF但我没有找到任何合

随机推荐

  • MySQL 数据库————连接查询

    目录 一 多表连接查询 1 内连接 inner join 2 左连接 left join 3 右连接 right join 二 存储过程 1 简介 2 优点 3 语法 参数分类 带参数的存储过程 修改存储过程 删除存储过程 一 多表连接查询
  • VS2019安装和使用(C语言)

    VS2019视频 VS2022视频 博主看视频做的笔记 视频讲解比较详细更容易上手 一 下载 VS2019官网下载 分为三个版本 个人用户下载Community 2019足够了 登录微软账号免费 点击下载后跳转新页面可能要等一会才能弹出下载
  • 线性代数的深入理解

    线性代数笔记 关于矩阵理解 reference 矩阵理解 图片来源 b站上的教程 线性变换 所谓变换 其实就是空间里从一个点 元素 对象 到另一个点 元素 对象 的跃迁 矩阵是线性空间中的线性变换的一个描述 在一个线性空间中 只要我们选定一
  • 可正反插USB-C双口转HDMI/VGA带PD快充音视频产品设计方案AG9321MCQ设计参考电路

    ALGOLTEK AG9321MCQ系列为HDMI和VGA转换器提供USB C型 显示端口备用 的单片机解决方案 并提供电源传输 AG9321MCQ系列支持带片上Rp Rd的双USB C型插座 符合USB电源传输规范3 0 集成的10位AD
  • 【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)

    目录 一 链表基本概念和基本代码实现 二 链表 动态数组整合 面向接口编程 三 clear 四 add int index E element 1 找到 index 位置的节点 2 get int index 和 set int index
  • 前端入坑(四)--------react(如何从API获取数据)

    Hey Welcome to day 4 Hopefully you ve had time to follow along and do the exercises from the last few days And if I ve d
  • GIT : 记录IntelliJ IDEA 合并冲突时的一个bug(冲突解决后代码和本地仓库一样时导致merge失败)

    目录 目录 IntelliJ IDEA版本 问题描述 解决办法 IntelliJ IDEA版本 IntelliJ IDEA 2017 1 4 x64 问题描述 我们在用git开发是经常遇到冲突的情况 一般发生在协同开发时 一个文件被两个人同
  • Unity-Transform.eulerAngles

    Description The rotation as Euler angles in degrees The x y and z angles represent a rotation z degrees around the z axi
  • ReactJS之属性和状态的对比

    1 都是纯JS对象 2 都会触发render的执行 3 都有确定性 状态 state 是由组件本身进行维护和修改的 组件外部是无法进行修改的 属性 props 组件自身具有的特性 是无法被自身修改的 但是父组件是可以修改子组件的属性 子组件
  • 贝叶斯网络是神经网络吗,贝叶斯网络和神经网络

    深度信念网络与深度贝叶斯网络有什么区别 1 贝叶斯网络是 一种概率网络 它是基于概率推理的图形化网络 而贝叶斯公式则是这个概率网络的基础 贝叶斯网络是基于概率推理的数学模型 所谓概率推理就是通过一些变量的信息来获取其他的概率信息的过程 基于
  • 内网穿透NPS及NPC搭建(使用docker实现)

    客户端及服务端下载 NPS 1 启动NPS服务器容器 端口映射需要注意 docker run td rm p 10180 8080 p 10124 8024 p 10150 10179 10150 10179 name nps q01231
  • 遥感NDVI估算植被覆盖度

    遥感NDVI估算植被覆盖度 植被覆盖度是指植被 包括叶 茎 枝 在地面的垂直投影面积占统计区总面积的百分比 容易与植被覆盖度混淆的概念是植被盖度 植被盖度是指植被冠层或叶面在地面的垂直投影面积占植被区总面积的比例 两个概念主要区别就是分母不
  • php+redis实现对200w用户的即时推送服务

    欢迎加入 新群号码 99640845 怎么实现对200w用户的即时推送 这个推送可以理解为调用第三方的接口 push sms之类的东西 当时先写了一个demo 直接读取DB然后单个推送 结果 可想而知 于是设计一套基于redis php多进
  • EfficientNet的解读与Tensorflow 2.0实现

    EfficientNet论文解读 Efficient Net是Google在2019年发表的一篇论文 系统的研究了如何在给定资源的条件下 如何平衡扩展网络的深度 广度以及图像的分辨率这三者的关系 来取得最好的图像识别精度 作者提出了一种新的
  • part1:推荐一些适合练手、课程设计、毕业设计的python小项目源码,无任何下载门槛

    人生苦短 我用python 随着python这些年的流行 很多人开始使用python来实现各种功能 下面推荐一些适合用来练手 大学生课程设计作业 大学生毕业设计的python小项目 尤其适合新手 源码 说明文档 打包后的exe文件 都已经被
  • MCP2515独立控制器

    1 简介 MCP2515 是一款独立控制器局域网络 Controller Area Network CAN 协议控制器 完全支持 CAN V2 0B 技术规范 该器件能发送和接收标准和扩展数据帧以及远程帧 MCP2515 自带的两个验收屏蔽
  • GPU pytorch 1.4.0 cuda 10.1 安装

    安装版本 pytorch 1 4 0 torchvision 0 5 0 cudatoolkit 10 1 pytorch官网 第一步 安装 conda 镜像通道 conda config add channels https mirror
  • QT5开发

    摘要 Qt5主窗口是大部分Qt应用使用的基本界面 常见应用都会通过对主窗口进行界面布局来实现 一 QT5主窗口构成 1 基本元素 QMainWindow是一个为用户提供主窗口程序的类 包含一个菜单栏 menubar 多个工具栏 tool b
  • SpringMvc学习-2-Spring MVC 的核心组件

    Spring MVC 的核心组件 DispatcherServlet 核心处理器 也叫前端控制器 负责调度其他组件的执行 可降低不同组件之间的耦合性 是整个 Spring MVC 的核心模块 Handler 处理器 完成具体业务逻辑 相当于
  • Java 8: 从永久代(PermGen)到元空间(Metaspace)

    正如大家所知 JDK 8 Early Access版已经提供下载 这使开发者可以体验Java8的新特性 其中之一 是Oracle从JDK7发布以来就一直宣称的要完全移除永久代空间 例如 字符串内部池 已经在JDK7中从永久代中移除 JDK8