JDK1.6在永久代没有被移除的时候,永久代属于堆的一部分嘛,如果在堆里那-XX:MaxPermSize的值是否必须小于-Xmx?如果不在堆里去除-XX:MaxPermSize不就和元空间一样了嘛都可以无限大小只受限于操作系统内存?
不在堆里面。但是也是有默认大小的,所以有时候项目太大了,是要把永生代的空间改大一点。
JDK1.6在永久代没有被移除的时候,永久代不在堆里去除-XX:MaxPermSize不就和元空间一样了嘛都可以无限大小只受限于操作系统内存
方法区(Method Area) 与Java堆一样, 是各个线程共享的内存区域, 它用于存储已被虚拟机加载
的类型信息、 常量、 静态变量、 即时编译器编译后的代码缓存等数据。 虽然《Java虚拟机规范》 中把
方法区描述为堆的一个逻辑部分, 但是它却有一个别名叫作“非堆”(Non-Heap) , 目的是与Java堆区
分开来。
说到方法区, 不得不提一下“永久代”这个概念, 尤其是在JDK 8以前, 许多Java程序员都习惯在
HotSpot虚拟机上开发、 部署程序, 很多人都更愿意把方法区称呼为“永久代”(Permanent
Generation) , 或将两者混为一谈。 本质上这两者并不是等价的, 因为仅仅是当时的HotSpot虚拟机设
计团队选择把收集器的分代设计扩展至方法区, 或者说使用永久代来实现方法区而已, 这样使得
HotSpot的垃圾收集器能够像管理Java堆一样管理这部分内存, 省去专门为方法区编写内存管理代码的
工作。 但是对于其他虚拟机实现, 譬如BEA JRockit、 IBM J9等来说, 是不存在永久代的概念的。 原则
上如何实现方法区属于虚拟机实现细节, 不受《Java虚拟机规范》 管束, 并不要求统一。 但现在回头
来看, 当年使用永久代来实现方法区的决定并不是一个好主意, 这种设计导致了Java应用更容易遇到
内存溢出的问题(永久代有-XX: MaxPermSize的上限, 即使不设置也有默认大小, 而J9和JRockit只要
没有触碰到进程可用内存的上限, 例如32位系统中的4GB限制, 就不会出问题) , 而且有极少数方法
(例如String::intern()) 会因永久代的原因而导致不同虚拟机下有不同的表现。 当Oracle收购BEA获得了
JRockit的所有权后, 准备把JRockit中的优秀功能, 譬如Java Mission Control管理工具, 移植到HotSpot
虚拟机时, 但因为两者对方法区实现的差异而面临诸多困难。 考虑到HotSpot未来的发展, 在JDK 6的
时候HotSpot开发团队就有放弃永久代, 逐步改为采用本地内存(Native Memory) 来实现方法区的计
划了[1], 到了JDK 7的HotSpot, 已经把原本放在永久代的字符串常量池、 静态变量等移出, 而到了
JDK 8, 终于完全废弃了永久代的概念, 改用与JRockit、 J9一样在本地内存中实现的元空间(Metaspace) 来代替, 把JDK 7中永久代还剩余的内容(主要是类型信息) 全部移到元空间中。
《Java虚拟机规范》 对方法区的约束是非常宽松的, 除了和Java堆一样不需要连续的内存和可以选
择固定大小或者可扩展外, 甚至还可以选择不实现垃圾收集。 相对而言, 垃圾收集行为在这个区域的
确是比较少出现的, 但并非数据进入了方法区就如永久代的名字一样“永久”存在了。 这区域的内存回
收目标主要是针对常量池的回收和对类型的卸载, 一般来说这个区域的回收效果比较难令人满意, 尤
其是类型的卸载, 条件相当苛刻, 但是这部分区域的回收有时又确实是必要的。 以前Sun公司的Bug列
表中, 曾出现过的若干个严重的Bug就是由于低版本的HotSpot虚拟机对此区域未完全回收而导致内存
泄漏。
根据《Java虚拟机规范》 的规定, 如果方法区无法满足新的内存分配需求时, 将抛出
OutOfMemoryError异常。
您好,我是有问必答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题,可以追评进行沟通哦~
如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~
ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632