聊聊jvm的PermGen与Metaspace
转载:https://segmentfault.com/a/1190000012577387
序
本文主要讲述一下jvm的PermGen与Metaspace
java memory结构
分代概念
对于垃圾收集算法来说,分代回收是高级算法之一。对象按照生成时间进行分代,刚刚生成不久的年轻对象划为新生代(Young gen-eration),而存活了较长时间的对象划为老生代(Old generation)。根据具体实现方式的不同,可能还会划分更多的代。比如有的把永久代也算做一个代。
memory划分
java memory主要分heap memory 和 non-heap memory,其计算公式如下:
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]
- heap结构
按分代,分young-eden,young-survivor,old
用-Xmn,-Xms,-Xmx来指定
- non-heap结构
包括metaspace,thread stacks,compiled native code,memory allocated by native code
-XX:PermSize或-XX:MetaspceSize,-Xss或-XX:ThreadStackSize
PermGen与Metaspace
字符串常量池的变化
- 在java7的时候将字符串常量池则移到java heap
所有的被intern的String被存储在PermGen区.PermGen区使用-XX:MaxPermSize=N来设置最大大小,但是由于应用程序string.intern通常是不可预测和不可控的,因此不好设置这个大小。设置不好的话,常常会引起
java.lang.OutOfMemoryError: PermGen space
- java7,8的字符串常量池在堆中实现
字符串常量池被限制在整个应用的堆内存中,在运行时调用String.intern()增加字符串常量不会使永久代OOM了。
方法区的变化
- java8的时候去除PermGen,将其中的方法区移到non-heap中的Metaspace
move name and fields of the class, methods of a class with the bytecode
of the methods, constant pool, JIT optimizations etc to metaspace
- Metaspace属于non-heap
Metaspace与PermGen之间最大的区别在于:Metaspace并不在虚拟机中,而是使用本地内存。
如果没有使用-XX:MaxMetaspaceSize来设置类的元数据的大小,其最大可利用空间是整个系统内存的可用空间。JVM也可以增加本地内存空间来满足类元数据信息的存储。
但是如果没有设置最大值,则可能存在bug导致Metaspace的空间在不停的扩展,会导致机器的内存不足;进而可能出现swap内存被耗尽;最终导致进程直接被系统直接kill掉。
- OOM异常
如果类元数据的空间占用达到MaxMetaspaceSize设置的值,将会触发对象和类加载器的垃圾回收。
java.lang.OutOfMemoryError: Metaspace space
JVM从Metaspace在捕获一个一个内存分配失败后抛出。
Metaspace相关参数
- -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
- -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
- -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集
- -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
小结
将常量池从PermGen剥离到heap中,将元数据从PermGen剥离到元数据区,去除PermGen的好处如下:
- 将字符串常量池从PermGen分离出来,与类元数据分开,提升类元数据的独立性
- 将元数据从PermGen剥离出来到Metaspace,可以提升对元数据的管理同时提升GC效率。
在PermGen中元数据可能会随着每一次Full GC发生而进行移动。HotSpot虚拟机的每种类型的垃圾回收器都需要特殊处理PermGen中的元数据,分离出来以后可以简化Full GC以及对以后的并发隔离类元数据等方面进行优化。
- 为后续将HotSpot与JRockit合二为一做准备。
PermGen是HotSpot的实现特有的,JRockit并没有PermGen一说
doc
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)
- JVM内存调优相关的一些笔记(杂)
- Java PermGen 去哪里了
- 一个Tomcat配置参数引发的血案
- Java6,7,8中的String.intern() – 字符串常量池
- 升级Java8可能会踩到的坑
聊聊jvm的PermGen与Metaspace的更多相关文章
- 聊聊jvm的CompressedClassSpace
序本文主要研究一下jvm的CompressedClassSpace CompressedClassSpacejava8移除了permanent generation,然后class metadata存 ...
- Metaspace 之二--PermGen vs. Metaspace 运行时比较
PermGen vs. Metaspace 运行时比较 为了更好地理解Metaspace内存空间的运行时行为, 将进行以下几种场景的测试: 使用JDK1.7运行Java程序,监控并耗尽默认设定的85M ...
- 聊聊JVM的年轻代(转)
聊聊JVM的年轻代 本文转自http://ifeve.com/jvm-yong-generation/ 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代 ...
- 推荐一下《聊聊JVM》的专栏
依照惯例新开了一个专栏后要单推一下.推荐一下<聊聊JVM的专栏>,网上关于JVM的文章太多,这个专栏希望能在已有的资料的基础上写出点新意,对一些重要的概念归纳总结,说说自己的观点.理解和实 ...
- JVM元空间(Metaspace)
本文转载自JVM学习--元空间(Metaspace) 从方法区(PermGen)到元空间(Metaspace) 方法区(PermGen) JDK1.8以前的HotSpot JVM有方法区,也叫永久代( ...
- 聊聊JVM的年轻代
1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的 唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候 ...
- 【JVM】6、聊聊JVM常用参数设置
整体考虑堆大小 -Xms3550m, 初始化堆大小.通常情况和-Xmx大小设置一样,避免虚拟机频繁自动计算后调整堆大小. -Xmx3550m,最大堆大小. 考虑分代设置堆大小 首先通过jstat等工具 ...
- 聊聊JVM(二)说说GC的一些常见概念
转自CSDN 上一篇总结GC的基础算法,各种GC收集器的基本原理,还是比较粗粒度的概念.这篇会整理一些GC的常见概念,理解了这些概念,相信对GC有更加深入的理解 1. 什么时候会触发Minor GC? ...
- 聊聊jvm系列
http://blog.csdn.net/column/details/talk-about-jvm.html
随机推荐
- LoadRunner 执行单句SQL语句
LoadRunner 执行单句SQL语句 Action() { int NumRows=0; int i=1; //建立数据库连接 lr_db_connect("StepName=Datab ...
- OpenStack 认证服务 KeyStone连接和用户管理(五)
一) 创建环境变量链接keyston vim adminrc export OS_USERNAME=admin export OS_PASSWORD=redhat export OS_PROJECT_ ...
- Storm基本概念以及Topology的并发度
Spouts,流的源头 Spout是Storm里面特有的名词,Stream的源头,通常是从外部数据源读取tuples,并emit到topology Spout可以同时emit多个tupic strea ...
- PM过程的一些典型场景和问题
如何进行团队激励 如何进行目标管理 如何进行绩效考核 如何处理团队沟通(技巧) 详述几种软件过程理论 需求分析和度量 测试过程和工具 开发管理过程
- bzoj 4602: [Sdoi2016]齿轮
4602: [Sdoi2016]齿轮 Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合 ...
- SourceTree运行慢的解决方案
以下两个Git命令可以解决SourceTree运行慢: git gc git prune 可以在SourceTree点击命令行模式打开Git命令行窗口输入,等待片刻执行完成,SourceTree的运行 ...
- Java编程思想学习(三)----第三章:操作符
3.2使用Java操作符 操作符接受一个或多个参数,并生成一个新值. 操作符作用于操作数,生成一个新值.有些操作符可以改变操作数自身的值.几乎所以的操作符都只能操作“基本类型”.例外的操作符有“=”, ...
- C - 壮志难酬
#include<stdio.h> #include<stdlib.h> #include<string.h> int main() { ]= {'}; int i ...
- web安全之如何防止CSRF跨站请求伪造
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站 ...
- 【很变态】PHP类实例化对象竟然可以访问类的“静态(static)方法”!!!
之前发现一个PHP的变态问题:PHP中静态(static)调用非静态方法详解 这次看了下 ThinkPHP 的源码 function.inc.php ,里面有个函数: /** * 取得对象实例 支持调 ...