本文阅读时间大约4分钟。

JVM加载类的时候,需要记录类的元数据,这些数据会保存在一个单独的内存区域内,在Java 7里,这个空间被称为永久代(Permgen),在Java 8里,使用元空间(Metaspace)代替了永久代。永久代和元空间保存的数据并不完全一样,永久代中还保存另一些与类的元数据无关的杂项。

如我们之前的一篇文章

理论学习

使用Java 8以后,关于元空间的JVM参数有两个:-XX:MetaspaceSize=N-XX:MaxMetaspaceSize=N,对于64位JVM来说,元空间的默认初始大小是20.75MB,默认的元空间的最大值是无限。MaxMetaspaceSize用于设置metaspace区域的最大值,这个值可以通过mxbean中的MemoryPoolBean获取到,如果这个参数没有设置,那么就是通过mxbean拿到的最大值是-1,表示无穷大。

由于调整元空间的大小需要Full GC,这是非常昂贵的操作,如果应用在启动的时候发生大量Full GC,通常都是由于永久代或元空间发生了大小调整,基于这种情况,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大,对于8G物理内存的机器来说,一般我会将这两个值都设置为256M(PS:读者可以根据自己的实际情况再调整)。

源码分析

MetaspaceSize表示metaspace首次使用不够而触发FGC的阈值,只对触发起作用,原因是:垃圾搜集器内部是根据变量 _capacity_until_GC来判断metaspace区域是否达到阈值的,初始化代码如下所示:

void MetaspaceGC::initialize() {
// Set the high-water mark to MaxMetapaceSize during VM initializaton since
// we can't do a GC during initialization.
_capacity_until_GC = MaxMetaspaceSize;
}

GC收集器会在发生对metaspace的回收会,会计算新的capacityuntil_GC值,以后发生FGC就跟MetaspaceSize没有关系了。

如果不设置MetaspaceSize,则默认的capacityuntil_GC为20M左右,具体代码如下:

往期精选

本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。

文章好看就点这里

JVM参数最佳实践:元空间的初始大小和最大大小的更多相关文章

  1. JDK8的JVM内存结构,元空间替代永久代成为方法区及常量池的变化

    JVM的知识这里总结的很详细:https://github.com/doocs/jvm/blob/master/README.md,因此在本博客也不会再对其中的东西重复总结了. 现在很多文章关于JVM ...

  2. Docker Daemon 参数最佳实践

    1. Docker Daemon 配置参数 限制容器之间网络通信 在同一台主机上若不限制容器之间通信,容器之间就会暴露些隐私的信息,所以推荐关闭 docker daemon –icc=false 使用 ...

  3. 启动Activity,传递参数最佳实践

    优化后的好处不言而喻,OtherActivity中所需要的参数都在方法参数中体现,减少了交流询问的成本. (1)MainActivity.java OtherActivity.openActivity ...

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

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

  5. JVM 知识点补充——永久代和元空间

    之前已经讲过了不少有关 JVM 的内容,今天准备将之前没有细讲的部分进行补充,比如:永久代和元空间. 永久代 Java 的内存中有一块称之为方法区的部分,在 JDK8 之前, Hotspot 虚拟机中 ...

  6. Metaspace 之二--Java 8的元空间(metaspace)、metaspace监控方法

    很多开发者都在其系统中见过“java.lang.OutOfMemoryError: PermGen space”这一问题.这往往是由类加载器相关的内存泄漏以及新类加载器的创建导致的,通常出现于代码热部 ...

  7. JVM学习笔记二:JVM参数

    所有线程共享的内存主要有两块:堆内存和方法区. 其中堆内存分为两块:新生代Young generation(Eden区.From Survivor区.To Survivor区).老年代Tenured ...

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

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

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

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

随机推荐

  1. Junit框架使用(4)--JUnit常用断言及注解

    从别人博客中抄过来一点东西 原文地址:http://blog.csdn.net/wangpeng047/article/details/9628449 断言是编写测试用例的核心实现方式,即期望值是多少 ...

  2. HDU 6588 Function

    [传送门] 求$$\sum_{i=1}^{n} \gcd(\lfloor \sqrt[3]{i} \rfloor, i)$$题解写的很清楚,自己重新推一推. $$\sum_{i=1}^{n} \gcd ...

  3. yum 初始化国内

    修改为阿里源备份默认的yum源文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载阿里 ...

  4. js的call()方法

    // ① 当函数中没有this时,call().apply()和直接执行没有区别 function fn(){ console.log("aaa") } fn() // aaa f ...

  5. requests--会话对象,ssl验证

    会话对象 前面我们使用了添加cookie的方式来进行接口的访问,如果有几十个接口都要依赖登录,难道我们都要加上吗? Request的会话对象让你能够跨请求保持某些参数,它也会在同一请求Session实 ...

  6. [LeetCode] 32. Longest Valid Parentheses 最长有效括号

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  7. QSS文件美化界面无效

    问题描述: 同样的qss内容,内置有效,写进qss文件加载无效. 搜寻.........很多网友的经理是qss文件编码和qt文本编辑器的属性........而我怎么尝试,怎么失败. 解决方案: 从fi ...

  8. 工作中常用的Linux命令介绍与实践

    前言 做后端开发的同学,一般都会接触到服务器,而我们现在的系统用的比较多的服务器系统就是linux了,平时多多少少也会接触到一些linux下的shell命令.我们来介绍下linux一些常用的命令和使用 ...

  9. Idea必知必会

    声明:此文章根据后续用的越来越多,将会不断补充,之所以以链接的形式,是因为不想在这种使用层面上重复造轮子,写很多重复文章,后续我打算写一些更深入的文章. idea常用操作: idea如何Debug调试 ...

  10. Oracle函数sys_connect_by_path用法

    sys_connect_by_path函数是为了配合递归查询的函数,递归查询可以参考我之前的博客:https://blog.csdn.net/u014427391/article/details/84 ...