永久代(PermGen)

在自定义类加载器还不是很常见的时候,类大多是static的,很少被卸载或收集,因此被成为“永久的(Permanent)”。同时,由于类class是JVM实现的一部分,并不是由应用创建的,所以又被认为是“非堆(Non-Heap)”内存。

  • 在JDK8之前的HotSpot JVM,存放这些“永久的”区域叫做“永久代(permanent generation)”。
  • 永久代是一片连续的堆空间,在JVM启动之前通过在命令行设置参数-XX:MaxPermSize
    -XX:MaxPermSize:永久代的最大可分配内存空间。默认大小64M(64位JVM由于质真膨胀,默认是85M)。当JVM加载的类信息容量超过了参数设定的值时,应用将会报OOM的错误
  • 永久代的垃圾收集和老年代(old generation)捆绑在一起,因此无论哪个满了,都会出发永久代和老年代的垃圾收集。
  • java.lang.OutOfMemoryError:PremGen space
    这里的“PermGen space”其实指的就是方法区。不过方法区和“PermGen space”又有着本质的区别。前者是JVM的规范,而后者则是JVM规范的一种实现。并且只有HotSpot才有“PermGen space”,而对于其他类型的虚拟机,如JRockit(Oracle)、J9(IBM)并没有“PermGen space”。
  • 由于方法区主要存储类的相关信息,所以对于动态生成类的情况比较容易出现永久代的内存溢出。并且JDK 1.8中参数PermSize和MaxPermSize已经失效
  • 移除永久代的工作从JDK 1.7就开始了。JDK 1.7中,存储在永久代的部分数据就已经转移到Java Heap或者Native Heap。但永久代仍存在于JDK 1.7中,并没有完全移除,譬如符号引用(Symbols)转移到了Native Heap;字面量(interned strings)转移到了Java Heap;类的静态变量(class statics)转移到了Java Heap。
  • G1 VS CMS:在JDK7 update 4即随后的版本中,提供了完整的支持对于Garbage-First(G1)垃圾收集器,以取代在JDK5中发布的CMS收集器。
    使用G1,PermGen仅仅在FullGC(stop-the-word,STW)时才会被收集。G1仅仅在PermGen满了或者应用分配内存的速度比G1并发垃圾收集速度快的时候才触发FullGC。
    而对于CMS收集器,通过开启布尔参数-XX:+CMSClassUnloadingEnabled来并发对PermGen进行收集。对于G1没有类似的选项,G1只能通过FullGC,stop the world,来对PermGen进行收集。

元空间(MetaSpace)

JDK8不再有PermGen,对JVM架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到Java堆里。
HotSpot JVM将会为类的元数据明确分配和释放本地内存。在这种架构下,类元信息就突破了原来-XX:MaxPermSize的限制,现在可以使用更多的本地内存。这样就从一定程度上解决了原来在运行时生成大量类造成经常Full GC问题,如运行时使用反射、代理等。所以升级以后Java堆空间可能会增加。

  • 大部分类元数据都在本地内存中分配
  • 默认情况下,类元数据只受可用的本地内存限制(容量取决于是32/64位操作系统的可用虚拟内存大小)
  • 新参数MaxMetaspaceSize用于限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整。
  • 僵死的类及类加载器的垃圾回收:将在元数据使用达到MaxMetaspaceSize参数的设定值时进行
  • 适时地监控和调整元空间对于减少垃圾回收频率和减少延时是很有必要的
    持续的元空间垃圾回收说明,可能存在类、类加载器导致的内存泄露或是大小设置不合适。

类元数据信息放到MetaSpace原因

  • PermGen很难调整
    PermGen中类的元数据信息在每次FullGC的时候可能会被收集,但成绩很难令人满意。而应该为PermGen分配多大的空间很难确定,因为PermSize的大小依赖于很多因素,如JVM加载的class总数,常量池的大小,方法的大小等等。
  • HotSpot中的每个垃圾收集器需要专门的代码来处理存储在PermGen中的类的元数据信息
    从PermGen分离类的元数据信息到MetaSpace,由于MetaSpace的分配具有和Java Heap相同的地址空间,因此MetaSpace和Java Heap可以无缝的管理,而且简化了FullGC的过程,以至将来可以并行的堆元数据信息进行垃圾收集,而没有GC暂停。

元空间特点

  1. 每个加载器有专门的存储空间
  2. 不会单独回收某个类
  3. 元空间里的对象的位置是固定的
  4. 如果发现某个加载器不再存货了,会把相关的空间整个回收

两者区别

元空间不在虚拟机中,使用的是本地内存;永久代使用的是JVM内存
可以通过-XX:MetaspaceSize和-XX:MaxMetaspaceSize参数来指定原空间的大小

元空间相比永久代的优势

  • 字符串常量池存在永久代中,容易出现性能问题和内存溢出
  • 类和方法的信息大小难以确定,给永久代的代销指定带来困难
  • 永久代会为GC带来不必要的复杂性
  • 方便HotSpot与其他JVM如Jrockit的集成

永久代的移除对最终用户意味着什么?

由于类的元数据可以在本地内存(native memory)之外分配,所以其最大可利用空间是整个系统内存的可用空间。这样,你将不再会遇到OOM错误,溢出的内存会涌入到交换空间。最终用户可以为类元数据指定最大可利用的本地内存空间,JVM也可以增加本地内存空间来满足类元数据信息的存储。
:永久代的移除并不意味者类加载器泄露的问题就没有了。因此,你仍然需要监控你的消费和计划,因为内存泄露会耗尽整个本地内存,导致内存交换(swapping),这样只会变得更糟。

补充问题

【JVM】元空间、堆、栈独占部份间的联系——内存角度

【JVM】元空间与永久代区别相关推荐

  1. Jvm元空间存哪些数据

    Java内存模型的内部结构取决于使用哪个JVM,尽管在高层的情况是相似的.JVM中有两个主要的内存区域-堆和堆栈.局部变量和方法驻留在堆栈上,其他的都在堆上. Java堆内存结构 Java堆内存分为不 ...

  2. 012、JVM实战总结:案例实战:每日百万交易的支付系统,JVM栈内存与永久代大小又该如何设置?

    更详细内容请扫描上方的二维码 1.前文回顾 如何根据对未来预估的业务量和访问量去推算每秒的并发量.内存空间占用等,进而推算出内存运转模型,然后选择合理的机器配置,配置合理的内存大小 2.基于案例,说说 ...

  3. JVM之 方法区、永久代(PermGen space)、元空间(Metaspace)三者的区别

    文章目录 0.前言(JVM 运行时区域) 1.PermGen(永久代) 2.Metaspace(元空间) 3.JDK6 .JDK7.JDK8 内存溢出的示例 4.元空间与本地内存 5.总结 0.前言( ...

  4. JVM原理系列--元空间(MetaSpace)与永久代(PermGen)的区别

    原文网址:JVM原理系列--元空间(MetaSpace)与永久代(PermGen)的区别_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍JVM中元空间(MetaSpace)与永久代(PermG ...

  5. JVM之方法区、永久代(PermGen space)、元空间(Metaspace)三者的区别

    JVM体系结构 根据 JVM 规范,JVM 运行时区域大致分为 方法区.堆.虚拟机栈.本地方法栈.程序计数器 五个部分. 1).方法区 方法区是JVM 所有线程共享. 主要用于存储类的信息.常量池.方 ...

  6. JVM 1.8 永久代---元空间 的变动

    介绍JVM的内存模型的博客:https://blog.csdn.net/q5706503/article/details/84614158 JDK8 HotSpot JVM 将移除永久区,使用本地内存 ...

  7. JVM运行时数据区域——为什么jdk8用元空间替换了永久代

    以局部窥全局,这个问题其实很复杂,要弄清楚这个问题,首先要对JVM运行时数据区域划分以及各个数据区域的作用了和指掌. JVM运行时数据区域总览 JVM在执行Java程序的过程中(简称运行时)会把它所管 ...

  8. jvm系列二:Java8内存模型-永久代(PermGen)和元空间(Metaspace)

    原文地址:https://www.cnblogs.com/paddix/p/5309550.html 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地 ...

  9. 面试官 | JVM 为什么使用元空间替换了永久代?

    7:40到11:40历时4个小时完成了该文,看到电脑中左边的便签了么,我也是拼了. 在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为 ...

最新文章

  1. python安装完后无法打开运行_安装Python完成后无法正确运行
  2. 系统练级攻略 | 京东架构师倾情解读
  3. 自学Springboot(一)
  4. 输变电设备物联网节点设备无线组网协议_U-Link 物联网(工业互联网)服务平台
  5. 使用.NET开发的数据库小工具 DbTool
  6. 2017 ACM Jordanian Collegiate J.Efficiency Test 动态规划、类倍增
  7. 微擎即用WIFI源码V2.1.7
  8. 在STM8单片机中自己实现 printf()函数功能
  9. vasp544编译安装
  10. Spring源码分析-Bean生命周期概述
  11. python上方菜单栏不见了如何恢复_CorelDRAW菜单栏不见了,如何恢复
  12. 基于GMap.NET库实现的Windows桌面地图工具软件分享
  13. 软件技术java开发方向,22年最新
  14. 2005年商业科技盘点:最被高估10大技术
  15. 奥斯汀页眉怎么设置_word红头文件怎么制作
  16. 解决:发生系统错误 5;拒绝访问!
  17. linux php gettext,在Ubuntu上无法获取gettext(php)工作
  18. 【老罗笔记】一万小时天才理论
  19. 大泉州汽车网整站程序PHP生成html开源版 V2018.1.1
  20. 名家丨 顾险峰:当深度学习遇到3D

热门文章

  1. python简单的分形图片
  2. pdf转换器电脑版免费,好用的办公操作软件集合
  3. Saruman‘s Army
  4. Python-List
  5. requests库请求获取不到数据怎么办?不妨试试看这种妙法
  6. 修改unbantu source.list Command ‘deb‘ not found, did you mean问题
  7. LUA调用C(一)-----CAPI
  8. 电脑win10系统如何开定位服务器,Win10系统定位功能如何打开 Win10系统定位打开方法...
  9. 华为GaussDB数据库10个知识点,第7个你知道么?
  10. 30句瞬间使你清醒的话,别再假装糊涂下去了!