专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

杂记-几个JVM(针对HotSpot)的容易忽视的问题

前言

分享几个JVM的容易忽视的问题,希望对大家有所帮助

哪些区域会出现OOM?

Java堆溢出

  • 我们知道,JVM参数配置中-Xms表示JVM启动时分配的内存、-Xmx表示JVM运行过程中最大可用内存。
  • 由此可见,随着对象实例增多,超过最大堆分配内存的限制,就会出现OOM。

栈溢出

  • 栈内存容量参数由-Xss决定,而栈内存取决于栈帧数量,即栈深度,以及每个栈帧的大小
  • 虚拟机栈常见的2种异常分为OOM以及StackOverflowError,那么,取决于什么情况,会抛相应的异常呢?

取决于栈内存是否支持扩展,HotSpot虚拟机不支持扩展

  • 由于HotSpot虚拟机不支持扩展,因此OOM的发生情况:创建线程时就因为无法获得足够内存而出现OOM,创建线程时内存不足,恰恰原因可能是每个线程的栈分配内存设置过大,在操作系统内存使用状态的影响下发生。
  • 例如,递归调用导致栈深度过大、定义大量本地变量增加栈帧中本地变量表长度,超过了-Xss所决定的栈内存容量,就会抛出StackOverflowError

方法区和运行时常量池溢出

[小插曲]方法区和常量池的关系?

  • 运行时常量池是方法区的一部分
  • 方法区存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。
  • 运行时常量池:常量池表,用于存放编译期生成的各种字面量与符号引用。(运行时也可以将新的常量放入池中,例如String::intern()

[小插曲]方法区 == 永久代?

  • 可以说,HotSpot虚拟机使用永久代来实现方法区,这两者不等价。
  • JDK 7的HotSpot,把原本放在永久代的字符串常量池String::intern()、静态变量等移出到堆内存;JDK8完全放弃永久代,改用本地内存的元空间(类型信息也移到了元空间)。

回归正题

  • 因此,如果使用String::intern()来制造方法区和常量池的OOM

1、JDK6或更早:字符串常量池大小增长,导致永久代的内存大小超过-XX:MaxPermSize规定的大小,导致出现PermGen space出现OOM。 2、JDK7开始,字符串常量池移入Java堆中,使用String::intern()报出OOM也是Java heap space

CGLib产生大量的类填充方法区,制造OOM

  • 1、JDK7出现PermGen space出现OOM
  • 2、JDK8出现Java heap space

GC Roots指什么?

  • 虚拟机栈中引用的对象,各个线程被调用的方法中使用到的参数、局部变量、临时变量。
  • 方法区类静态属性引用的对象。
  • 方法区常量引用的对象,例如字符串常量池的引用。
  • Java虚拟机内部的引用,Class对象、异常对象、系统类加载器。
  • 同步锁持有的对象(Synchronized)。

参考

文章永久链接:https://tech.souyunku.com/40463

未经允许不得转载:搜云库技术团队 » 杂记-几个JVM(针对HotSpot)的容易忽视的问题

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们