jvm系列(十一):Java 8-从持久代到metaspace

转载自 jvm系列(十一):Java 8-从持久代到metaspace

Java 8介绍了一些新语言以及运行时新特点。其中一个特点便是完全移除了持久代(PermGen),自从Oracle公司发布了JDK1.7后就已经宣布了这个决定。还有比如内部字符串,从JDK1.7开始就从持久代移除了,JDK8的发布彻底废除了它。在这个部分,我们会讨论持久代的继任者:Metaspace。

当执行一个Java程序并出现了“泄露”类元数据对象时我们会比较HotSpot 1.7和HotSpot 1.8的运行时行为的不同点。

Metaspace:一个新的内存空间诞生了

JDK8 HotSpot JVM现在使用了本地内存来存储类元数据,被称为Metaspace,和Oracle JRockit以及IBM JVM类似。

好消息是它意味着java.lang.OutOfMemoryError:PermGen space问题会越来越少,也不再需要你去调整和监控内存空间。然而这种变化默认是可不见的,接下来我们给你展示的,是你仍然需要关注类元数据内存占用。请记住,这些新特点并不会很神奇的消除类和类加载器的内存泄露。你需要使用不同的方法和学习新的命名约定来找出问题的根源。

总结

1、持久代场景
    • 这块内存区域被完全移除。 
    • PermSize和MaxPermSize JVM 参数会被忽略,并且在启动的时候会给出警告信息。

2、Metaspace 内存分配模型 
    • 对于类元数据的大多数内存分配都不会发生在本地内存。 
    • 被用于描述类元数据的类对象被移除。

3、Metaspace 容量 
    • 默认的,类元数据分配限制于可用的本地内存 (容量大小依赖于你用32位jvm或者64位jvm的操作系统可用虚拟内存)。 
     • 新的标记已经可以使用 (MaxMetaspaceSize),它允许你限制用于类元数据的本地内存大小。如果你没有指定这个标记,Metaspace会根据运行时应用程序的需求来动态的控制大小。

4、Metaspace 垃圾收集 
    • 一旦类元数据的使用量达到了“MaxMetaspaceSize”指定的值,对于无用的类和类加载器,垃圾收集此时会触发。 
    • 为了控制这种垃圾收集的频率和延迟,合适的监控和调整Metaspace非常有必要。过于频繁的Metaspace垃圾收集是类和类加载器发生内存泄露的征兆,同时也说明你的应用程序内存大小不合适,需要调整。

5、Java 堆空间影响 
    •一些杂项数据被移到了Java堆空间。这意味着当你更新到JDK8后会观察到Java堆空间的增长。

6、Metaspace 监控 
    • Metaspace 的使用可以通过HotSpot 1.8的详细的GC日志输出观察到。 
    • 在基于b75上测试的时候Jstat 和 JVisualVM 还没有更新,旧的持久代空间引用依然存在。

足够的理论知识就介绍到这,让我们在行动中通过会发生泄露的Java程序来看看新的内存空间…

持久代 vs. Metaspace运行时比较


为了能更好的理解新的metaspace内存空间在运行时的行为,我们创建了一个会发生元数据泄露的java程序。你可以从这里下载。


下面的场景将会被测试: 
    • 使用JDK1.7运行这个Java程序,目的是为了监控和消耗设置好的128M持久代空间。 
    • 使用JDK1.8(b75)运行这个Java程序,目的是为了监控Metaspace内存空间的动态增长和垃圾收集。 
    • 使用JDK1.8(b75)运行这个Java程序,设置MaxMetaspaceSize为128M,目的是为了模拟Metaspace空间的消耗。

JDK 1.7 @64-bit – 持久代消耗 
    • 一个包含5万个配置好的迭代的程序 
    • 1024M的java堆 
    • 128M java持久代(-XX:MaxPermSize=128m) 



从JVisualVM里可以看到,持久代的消耗在加载了超过3万个类之后几乎达到了临界。我们也可以从Java程序和GC输出中看到这种消耗。 

 

现在让我们用HotSpot JDK 1.8 来执行这个程序。

JDK 1.8 @64-bit – Metaspace 动态大小 
    • 一个包含5万个配置好的迭代的程序 
    • 1024M的堆 
    • Java Metaspace空间:无限(默认) 


 



从详细的GC输出可以看到,JVM的metaspace的确动态的把本地内存从20M扩展到了320M,目的是为了适应增长的Java程序中类元数据的内存占用。我们也可以观察到JVM会尝试进行垃圾收集的事件,目的是为了消灭无用的类和类加载器对象。自从我们的Java程序开始泄露内存,JVM没有选择,只能动态扩展Metaspace内存空间。

这个程序可以运行5万次迭代而不会发生OOM事件,并且加载了超过5万个类。

让我们转移到我们最后一次测试场景:

JDK 1.8 @64-bit – Metaspace 消耗 
    • 一个包含5万个配置好的迭代的程序 
    • 1024M的堆 
     • Java Metaspace空间:128 MB (-XX:MaxMetaspaceSize=128m) 



从JVisualVM里可以看到,在加载了超过3万个类后,Metaspace消耗达到了临界,和用JDK1.7运行的结果类似。我们可以从程序和GC输出中看到这个结果。另一个有意思的观察结果是本地内存占用是指定最大值的2倍。这或许可以说明,一种好的调整metaspace扩容的策略有可能避免本地内存的浪费。

和用JDK1.7运行一样,我们指定了metaspace最大容量为128M,但它在我们程序里并不能完成5万次的迭代。新的OOM会被抛出。上面的OOM事件是在内存分配失败后由JVM从metaspace里抛出的。.

关于metaspace的总结


目前观察到的结果完全说明了合适的监控和调优是非常必要的,目的是为了尽量避免类似我们最后一种测试场景中过多的metaspace GC或者OOM触发的问题。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330929.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的控制反转,依赖注入和面向切面编程的理解

感谢http://blog.xiaohansong.com/2015/10/21/IoC-and-DI/ 的供图1.什么是控制? 如下图所示,我们看到了 软件系统中 对象的 高耦合现象。全体齿轮的转动由一个对象来控制,如类B。2.什么是 控制反转? 是用来对对象进行解耦。借助第…

在Spring Boot中使用切面统一处理自定义的异常

最近我们将项目的一个单独模块提取了一个微服务,这个微服务主要负责其他系统的接入。目的是发布主项目的时候不会影响到其他系统接入。在提取出的微服务中,需要定义一个正常返回的报文和异常返回的报文。正常返回报文就是正常业务返回的数据报文&#xf…

Java 8的新特性—终极版

转载自 Java 8的新特性—终极版 1. 简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。在本文中我们将学习这些新特性,并用实际的例子说明在…

ReviewForJob——java虚拟机的垃圾回收策略(个人总结)

理解jvm的垃圾回收策略,需要解决以下3个问题问题1:哪些内存需要回收?问题2:什么时候进行回收?问题3:怎样来回收?【解决问题1】哪些内存需要回收?jvm的内存区域有5大块:1&…

使用静态代理模式实现公用的报表导出功能

先聊一下什么是代理模式? 代理模式 给某个对象提供一个代理对象,并由代理独享控制对原对象的引用。什么意思呢?代理模式就有点像我们生活中常见的中介。 举个例子,我想买辆二手车,第一种方式是自己去找车源&#xff…

java前台线程(普通线程) 和 后台线程

【1】普通线程: 就是指 用户 创建的一般线程,具有个体性,不具有提供公共服务的性质,因此, 通常需要我们在 线程的 循环语句中 手动编写 循环结束语句,也即 线程运行终止的条件语句; 【2】后台线…

mysql中使用CASE WHEN

简单的使用CASE WHEN CASE SCORE WHEN A THEN 优 ELSE 不及格 END CASE SCORE WHEN B THEN 良 ELSE 不及格 END CASE SCORE WHEN C THEN 中 ELSE 不及格 END上面的sql等同于 CASE SCORE WHEN A THEN 优 WHEN B THEN 良 WHEN C THEN 中 ELSE 不及格 ENDTHEN后面的值与ELSE后面…

Java生成随机数的几种高级用法

转载自 进阶 | Java生成随机数的几种高级用法!言归正传,众所周知,随机数是任何一种编程语言最基本的特征之一。而生成随机数的基本方式也是相同的:产生一个0到1之间的随机数。看似简单,但有时我们也会忽略了一些有趣的…

Java 可重入锁内存可见性分析

转载自 深度好文 | Java 可重入锁内存可见性分析一个习以为常的细节之前在做 ReentrantLock 相关的试验,试验本身很简单,和本文相关的简化版如下:(提示:以下代码均可左右滑动) private static ReentrantLoc…

java正则表达式 ^expr 和 [^expr] 和 ^[^expr]的比较

public class Main {private static String[] array {"Jav", "Java", "Hello"}; public static void main(String[] args) {String[] regexs {"^Java", // 以 Java开头的字符串"[^Java]",// 除了 J a v a 之外 的任何字符…

优秀 Java 程序员写代码的风格

转载自 涨姿势 | 优秀 Java 程序员写代码的风格今天突发奇想,对编码习惯和 编程风格 很感兴趣,于是乎,找了一下关于编程风格(Java篇)的资料,希望对爱好编码或者开始学习编码的同学有帮助!来自《…

2017尼毕鲁笔试算法题

【1】题目: 给定一个无序数组,找到最长的单调自增子序列(不一定连续,但是顺序不能乱)的长度; 【2】看个荔枝:给定数组 [10, 9, 2, 5, 3, 7, 101, 18] 输出结果为 [2, 3, 7, 101]。。算法时间…

2018年不能错过的 14 个 Java 库

转载自 2018年不能错过的 14 个 Java 库下面是整理给你的 2018 年不应该错过的 14 个 Java 库包清单,多多少少大家应该都接触过一些,如果还没听过那就OUT了。GuiceGuice是一个Java 6以上支持依赖注入框架。由谷歌提供。OkHttpHTTP是现代网络的通讯方式。…

Spring MVC Boot Cloud 技术教程汇总

转载自 Spring MVC & Boot & Cloud 技术教程汇总昨天我们发布了Java成神之路上的知识汇总,今天继续。 Java成神之路技术整理(长期更新) 以下是Java技术栈微信公众号发布的关于 Spring/ Spring MVC/ Spring Boot/ Spring Cloud 的技术…

group by分组、having() 筛选组的用法

【1】选出 除语文学科外,且学科平均分大于60 的每个学科的最高最低分;

Java成神之路技术整理

转载自 Java成神之路技术整理以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新。 Java 基础篇Java 集合篇Java 多线程篇Java JVM篇Java 进阶篇Java 新特性篇Java 工具篇Java 书籍篇 Java基础篇 8张图带你…

RFC+JSF术语

RFC 请求注解(Request For Comments) JSF JavaServer Faces (JSF) is a Java specification for building component-based user interfaces for web applications.

图解 5 种 Join 连接及实战案例!(inner/ left/ right/ full/ cross)

转载自 图解 5 种 Join 连接及实战案例!(inner/ left/ right/ full/ cross) Join 连接在日常开发用得比较多,但大家都搞清楚了它们的使用区别吗??一文带你上车~~ 内连接 inner join 内连接是基于连接谓词…

接口、多态

一.接口 1.接口的定义和使用 接口名:和类名一样,首字母大写 public interface 接口名{//接口中的成员,一般写一些抽象方法 } public class 类名 implements 接口名{//复写接口中所有的抽象方法 } 2.接口的成员热点: &#xff0…

基础笔试编程题(jz)

【1】计算某个单词在某文件中出现的次数. // 计算某个单词在某文件中出现的次数. public class WordCounter {private static int counter;private static String path System.getProperty("user.dir") File.separator "src" File.separator "com…