你注意到了吗?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程序的输出日志中找到下面的异常:
1.Class metadata leak simulator
2.Author: Pierre-Hugues Charbonneau
4.ERROR: java.lang.OutOfMemoryError: Metadata space
5.Done!
正如预期的那样,设置元空间最大尺寸为128 MB,就像我们在JDK1.7中一样没有让我们完成我们的50K迭代的计划。JVM抛出一个新的OOM错误。上述OOM事件是由JVM从元空间在捕获一个一个内存分配失败后抛出。
 #metaspace.cpp 结束语
 我希望你能欣赏这个对新的Java8元空间的早期的分析和实验 。目前观测表明,为了远离类似在我们最后测试场景中出现的频繁的元空间GC和OOM的问题,适当的监控和调优是必须的。以后的文章中可能包括性能比较,以确定这一新功能相关的潜在性能改进。请随时提供任何意见。 

AVA 8 :从永久区(PermGen)到元空间(Metaspace)的更多相关文章

  1. Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)

    Java8内存模型—永久代(PermGen)和元空间(Metaspace) 查看原文点击传送门:http://www.cnblogs.com/paddix/p/5309550.html 提示:本文做了 ...

  2. (转)Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    背景:介绍java8中永久代到元空间的转变. Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法 ...

  3. Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...

  4. 转:Java8内存模型—永久代(PermGen)和元空间(Metaspace)

    一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...

  5. Java8内存结构—永久代(PermGen)和元空间(Metaspace)

    本文转载 作者:liuxiaopeng 博客地址:https://www.cnblogs.com/paddix/p/5309550.html 一.JVM 内存结构 根据 JVM 规范,JVM 内存共分 ...

  6. java 8中撤销永久代,引入元空间

    撤销永久代,引入元空间: 在 JDK 1.8 中,HotSpot 已经没有 “PermGen space”这个空间了,取而代之是一个叫做 Metaspace(元空间) 的东西. Java7中已经将字符 ...

  7. JVM体系结构之七:持久代、元空间(Metaspace) 常量池==了解String类的intern()方法、常量池介绍、常量池从Perm-->Heap

    一.intern()定义及使用 相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: public native String inter ...

  8. JVM元空间(Metaspace)

    本文转载自JVM学习--元空间(Metaspace) 从方法区(PermGen)到元空间(Metaspace) 方法区(PermGen) JDK1.8以前的HotSpot JVM有方法区,也叫永久代( ...

  9. 面试官,Java8 JVM内存结构变了,永久代到元空间

    在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...

  10. JAVA8 JVM内存结构变了,永久代到元空间

    在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...

随机推荐

  1. hibernate 一对多关联

    package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; import javax.persistenc ...

  2. AnjularJS小项目,小案例,练手,猜数字

    之前自己就学了点AnjularJS,都是在菜鸟教程里面将基础的只是大致过了一遍,没怎么自己动手做什么东西练练手,但还是觉得纸上得来终觉浅,得知此事要躬行啊,今天就做了个猜数字的小游戏,觉得效果还不错, ...

  3. C#定时任务的偷懒实现

    通常会有些定时任务的工作,例如每分钟统计一下xxx用户的xxx数量 或者 定时拉取下数据 之类的任务. 通常要实现定时调度功能和控制线程是否可以并发执行. 所以通常一个简单的小项目搞成大项目,但是使用 ...

  4. Linux上寻找并杀死僵尸进程

    转载: http://blog.csdn.net/shanzhizi/article/details/47320595 linux服务器上,多少会出现一些僵尸进程,下面介绍如何快速寻找和消灭这些僵尸进 ...

  5. Inno Setup 打包的文件以管理员权限执行

    最近发现一个问题,就是Inno Setup打包的程序安装完毕后执行需求管理员权限的程序的时候会失败( inno createprocess   须要提升),解决问题的最简单办法就是打包的后的程序也以管 ...

  6. GSM/GPRS/EDGE简介

    GSM 全球移动通信系统(Global System of Mobile communication),是全球应用最广泛的移动电话标准.GSM被认为是第二代移动通信标准(2G),同时它是一个开放的标准 ...

  7. Lintcode---二叉树的层次遍历(原型)

    给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 您在真实的面试中是否遇到过这个题? Yes 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 ...

  8. andorid HTTPS 不需要证书 VolleyEror: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not fou

    1.加证书(这里不说) 2.修改代码 import java.security.KeyManagementException;import java.security.NoSuchAlgorithmE ...

  9. Zynq GPIO 中断

    /* * Copyright (c) 2009-2012 Xilinx, Inc. All rights reserved. * * Xilinx, Inc. * XILINX IS PROVIDIN ...

  10. Django--ORM基础

    ORM(映射关系) 映射关系: 表名 <-------> 类名 字段 <-------> 属性 表记录 <------->类实例对象 创建表(建立模型) 在Djan ...