1.先说明一个事情就是在jdk1.8之后已经没有永久代被元空间取代,那么元空间在哪里

说明:元空间在本地内存,自然更不是所谓年老代等分代里。

Java PermGen去了哪里?

Java虚拟机(JVM)使用其类的内部表示,包含每个类的元数据,如类层次结构信息,方法数据和信息(如字节码,堆栈和变量大小),运行时常量池和已解析的符号引用和Vtables 。

在过去(当自定义类加载器不常见时),类大多是“静态的”并且很少被卸载或收集,因此被标记为“永久”。此外,由于类是JVM实现的一部分而不是由应用程序创建,因此它们被视为“非堆”内存。

对于JDK8之前的HotSpot JVM,这些“永久”表示将存在于称为“永久代”的区域中。这个永久代与Java堆是连续的,并且仅限于-XX:MaxPermSize,它必须在启动JVM之前在命令行上设置,或者默认为64M(64位缩放指针为85M)。永久世代的集合将与旧一代的集合联系在一起,因此无论何时满足,都将收集永久代和旧代。您可以立即调用的一个明显问题是依赖于-XX:MaxPermSize。如果类元数据大小超出-XX:MaxPermSize的范围,则应用程序将耗尽内存并且您将遇到OOM(内存不足)错误。

随着JDK8的出现,我们不再拥有PermGen。不,元数据信息没有消失,只是它所持有的空间不再与Java堆相邻。元数据现在已经移动到本机内存到称为“Metaspace”的区域。

由于PermGen很难调整,因此转向Metaspace是必要的。元数据可能随着每个完整的垃圾收集而移动。此外,很难确定PermGen的大小,因为它的大小取决于很多因素,例如类的总数,常量池的大小,方法的大小等。

此外,HotSpot中的每个垃圾收集器都需要专门的代码来处理PermGen中的元数据。从PermGen中分离元数据不仅允许Metaspace的无缝管理,而且还允许改进,例如简化完整垃圾收集以及将来并发分配类元数据。

删除永久空间对最终用户意味着什么?

由于类元数据是从本机内存分配的,因此最大可用空间是可用的总系统内存。因此,您将不再遇到OOM错误,并最终可能溢出到交换空间。最终用户可以选择为类元数据限制最大可用本机空间,或者用户可以让JVM按顺序扩展本机内存以容纳类元数据。

注意:删除PermGen并不意味着您的类加载器泄漏问题已经消失。所以,是的,您仍然需要监控您的消费并相应地进行计划,因为泄漏会最终消耗您的整个本机内存,从而导致交换变得更糟。

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/considerations.html

类元数据
Java类在Java Hotspot VM中具有内部表示,并称为类元数据。在以前版本的Java Hotspot VM中,类元数据是在所谓的永久生成中分配的。在JDK 8中,永久代被删除类元数据在本机内存中分配。默认情况下,可用于类元数据的本机内存量是无限制的。使用该选项MaxMetaspaceSize可以为用于类元数据的本机内存量设置上限

Java Hotspot VM显式管理用于元数据的空间。从操作系统请求空间,然后分成块。类加载器从其块中为元数据分配空间(块绑定到特定的类加载器)。为类加载器卸载类时,其块将被回收以供重用或返回到操作系统。元数据使用分配的空间mmap,而不是malloc。

卸载相应的Java类时,将释放类元数据。由于垃圾收集而卸载Java类,并且可能会导致垃圾收集以卸载类并释放类元数据。当为类元数据提交的空间达到一定水平(高水位线)时,会引发垃圾收集。在垃圾收集之后,可以根据从类元数据中释放的空间量来升高或降低高水位标记。将提高高水位标记,以免过早引起另一次垃圾收集。高水位标记最初设置为命令行选项的值MetaspaceSize。这是上升或下降基础上,选择MaxMetaspaceFreeRatio和MinMetaspaceFreeRatio。如果类元数据的可用空间占类元数据总承诺空间的百分比大于MaxMetaspaceFreeRatio,则高水位标记将降低。如果小于MinMetaspaceFreeRatio,则高水位标记将被提升。

为选项指定更高的值,MetaspaceSize以避免为类元数据引发早期垃圾收集。为应用程序分配的类元数据量取决于应用程序,并且不存在用于选择的一般准则MetaspaceSize。默认大小MetaspaceSize取决于平台,范围从12 MB到大约20 MB。

2.设置PretenureSizeThreshold直接在年老代分配内存

XX:PretenureSizeThreshold 的意思是超过这个值的时候,对象直接在old区分配内存

默认值是0,意思是不管多大都是先在eden中分配内存。

https://www.oracle.com/technetwork/systems/index-156457.html

如果年轻一代的规模很小,并且对象的大小很大,那么现在直接在老一代中创建对象。并发收集器中的选项 - XX:PretenureSizeThreshold = <字节大小>,可以启用该选项 以指示在旧一代中直接创建的阈值。这可以有效地用于创建长期存在的高速缓存,查找表等,并且不必经历在年轻一代中创建然后被复制到老一代的促销周期。请谨慎使用此选项,因为它会降低性能而不是改进性能。默认值为0,即在旧一代中不直接创建任何对象。

https://stackoverflow.com/questions/35526190/automatically-promoting-an-object-to-old-generation

https://stackoverflow.com/questions/24618467/size-of-huge-objects-directly-allocated-to-old-generation

https://stackoverflow.com/questions/2129044/java-heap-terminology-young-old-and-permanent-generations

https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

https://bugs.openjdk.java.net/browse/JDK-8050209

https://www.jianshu.com/p/f7cde625d849

参考《深入理解Java虚拟机 JVM高级特性与最佳实践.周志明著》

JVM设置对象直接进入年老代相关推荐

  1. Java虚拟机笔记(五):JVM中对象的分代

    为什么要分代 为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用, ...

  2. JVM的年轻代、年老代(老年代)和永生代(持久代)【Loadrunner性能调优】

    1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我 ...

  3. JVM分化回收机制(年轻代、年老代、永久代)

    分代回收机制:JVM将堆内存划分为Eden.Survivor和Tenured/Old空间. (Minor GC )年轻代 :Eden.Survivor.尽可能快的收集生命周期短的对象. 在年轻代中经历 ...

  4. JVM学习笔记之四:分代垃圾回收

    2019独角兽企业重金招聘Python工程师标准>>> 如图所示,在HotSpot虚拟机中共划分有三个代:年轻代(young generation),年老代(old generati ...

  5. 【JVM】对象存活判定算法、GC算法、STW、GC种类详解

    [JVM]对象存活判定算法.GC算法.STW.GC种类详解 文章目录 [JVM]对象存活判定算法.GC算法.STW.GC种类详解 GC主要关注的区域 垃圾标记阶段:对象存活判断 标记阶段:引用计数算法 ...

  6. JVM垃圾回收中新生代老生代的问题

    今天看了下Jvm中新生代和老年代的定义和解析,然后看到一篇博,把自己整懵了,还好后面应该是懂了. 首先是我看到的关于新生代和老年代相关的部分 转自https://www.cnblogs.com/gao ...

  7. 年老代过大有什么影响

    jvm系列 垃圾回收基础 JVM的编译策略 GC的三大基础算法 GC的三大高级算法 GC策略的评价指标 JVM信息查看 GC通用日志解读 jvm的card table数据结构 Java类初始化顺序 J ...

  8. 强引用置为null,会不会被回收及内存分配及年轻代年老代算法回收

    会,GC执行时,就被回收掉,前提是没有被引用的对象 https://blog.csdn.net/qq_33048603/article/details/52727991 一定要了解垃圾回收原理 首先我 ...

  9. 45.JVM调优策略、常见问题:内存泄漏(年老代堆空间被占满、持久代被占满、堆栈溢出、线程堆栈满、系统内存被占满)优化方法:优化目标、优化GC步骤、优化总结;案例分析(公司系统参数、网上给的配置参数)

    45.JVM调优策略 45.1.常见问题 45.1.1.内存泄漏 45.1.1.1.年老代堆空间被占满 45.1.1.2.持久代被占满 45.1.1.3.堆栈溢出 45.1.1.4.线程堆栈满 45. ...

最新文章

  1. C语言fgets()函数(以指定长度读取文件中的字符,并存入字符数组变量中)
  2. 越用越快的福禄克布线认证测试仪
  3. Spring MVC Boot Cloud 技术教程汇总(长期更新)
  4. [html] input元素size属性和width 的区别是什么?
  5. Vue 项目结构介绍
  6. node事件循环 EventEmitter 异步I/O Buffer缓冲区 模块
  7. 已测试:网上大神写的快手极速版脚本,autojs版快手极速版自动脚本下载
  8. 基于Qt的屏幕共享工具(含源码)
  9. php订阅号怎么借服务号权限,微信订阅号已经认证能否有网页授权功能
  10. postgres 导入纯文本数据txt
  11. ipa在线安装搭建_iOS12.4.1 越狱无法安装?教你百分百安装
  12. python 单词拆音节_使用Python查找音节
  13. MSYS2 环境搭建
  14. 【web搜索】学习笔记-层次汇合聚类HAC算法
  15. listen1在火狐浏览器安装的步骤和细节处理
  16. jquery寻找父子兄弟节点
  17. 2019年11月20日笔记
  18. 读书笔记:《过程咨询 III》
  19. 查询速度至少为160MHz的PC的制造商
  20. Android Studio键盘快捷键

热门文章

  1. 在Word2010中交叉引用插入参考文献
  2. samba服务器介绍
  3. U盘空闲空间格式化及自动挂载
  4. Fabric 测试网络 - 商业票据
  5. java(反射机制)
  6. Vue 学习——表格列表数据显示百分号%、显示数字改为自定义内容、数据表头下拉、点击筛选数据
  7. python re.compile() 详解——Python正则表达式
  8. 英文文献翻译的APP
  9. Numpy之logspace
  10. mybatis的JavaType和ofType区别