jvm(一)内存区域与内存溢出异常

在这里插入图片描述
图转载:https://cxlm.work/archives/jvm-memory

对象的创建:如果内存是有序的,用的就是“指针碰撞”,就是指针的挪动来分配内存,其实一般都提前分配一定的缓冲区域作为对象创建用的内存,当缓冲区的内存不足时才指针移动来分配内存

如果内存不是有序的,则采用就是为列表,来记录哪块的内存块是可用的,,
选择哪种方式是由java堆是否完整决定的,而java堆是否完整则由所采用的的垃圾回收器是否带有空间压缩整理的能力决定的

对象的内存布局:1、对象头;2、实例数据;3、对齐填充;
对象头:1、存储对象本身运行时的数据;2、类型指针,对象指向它元数据的指针;

对象的访问定位:
1、使用句柄池,但是两次指向,一次指向对象实例数据,一次指向对象类型数据。
但是好处就是稳定,即使对象被移动,稳定性很棒,就是两次指向费时
2、使用指针、更快

一个线程对应一个 JVM Stack(栈帧)。JVM Stack 中包含一组 Stack Frame。线程每调用一个方法就对应着 JVM Stack 中 Stack Frame 的入栈,方法执行完毕或者异常终止对应着出栈(销毁)。
当 JVM 调用一个 Java 方法时,它从对应类的类型信息中得到此方法的局部变量区和操作数栈的大小,并据此分配栈帧内存,然后压入 JVM 栈中。
在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法。

OutOfMemoryError
1.JAVA堆溢出

JAVA堆用于存储对象实例,只要不断的创建对象,并且保证GC Roots到这些对象之间有路径可以来避免垃圾回收机制清除这些对象,那么在对象数量达到最大堆的容量限制之后就会产生OOM异常

解决方案:先分析到底是出现了内存泄漏(无法释放已申请的内存空间)还是内存溢出(没有足够的内存空间使用)

内存泄漏:通过工具查看泄漏对象到GC Roots的引用链,于是就能够找到内存泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法回收,这样就可以准确的定位到内存泄漏的代码

内存溢出:检查JVM的堆参数,与机器物理内存相比看看是否可以调大,并且从代码上检查是否存在某些对象生命周期太长,持有状态时间太长等情况,减少程序运行期间内存的消耗

2.虚拟机栈和本地方法栈溢出

多线程环境下,当为每个线程分配的栈内存越大,就越容易产生内存溢出异常,因为操作系统分配给每个进程的内存是有限的,每个线程分配到的栈容量越大,可以建立的线程数量自然越少,建立线程就越容易把剩下的内存耗尽

多线程导致的内存溢出,减少最大堆和减少栈容量来获取更多的线程

解决方案:减少最大堆和减少栈容量来换取更多的线程

3.方法区和运行常量池溢出

运行常量池是方法区的一部分,方法区存放的是Class的相关信息,当运行时产生了大量的类了填满方法区时,再产生类就会导致OOM

比如大量的JSP或动态产生JSP文件的应用(JSP第一次运行需要编译为JAVA类),基于OSGI的应用(即同一个文件,被不同的类加载器加载也会视为不同的类)

解决方案:减少不必要的类的产生

4.本机直接内存溢出

物理机器内存不足,满足不了JVM需求了

转载:https://www.cnblogs.com/yinbiao/p/10613585.html

由于jdk8以后,元空间取代了永久代,所以,Hotspot提供了一些措施来保护元空间
1、设置元空间的最大值为-1,即不限制,或者说只限制与本地内存的大小
2、指定元空间的大小,当达到改值得时候机会触及垃圾收集进行类型卸载,同时收集器会对该值进行调整
3、指定元空间最小剩余空间百分比,可减少因为元空间不足导致的垃圾收集的频率

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值