【夹娃系列】java面试基础知识储备(¥2)——JVM内存划分和内存溢出异常的原因和解决方法

JVM内存划分

在这里插入图片描述

  • 堆:存放对象实例,被所有的线程共享的一块区域。垃圾收集器管理的主要区域。
  • 方法区:存储虚拟机加载的类信息,常量,静态变量,编译后的代码等数据。有时被成为永久代(HotSpot虚拟机上这么称谓)
  • 虚拟机栈:每一个方法在运行时都会产创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表中存放了编译期就知道的各种基本数据类型,对象的引用等。常见的错误为:StackOverflowError
  • 本地方法栈:为虚拟机使用到的本地方法服务。很多虚拟机中将虚拟机栈和本地方法栈合二为一。其作用和虚拟机栈是一样的。
  • 程序计数器:占用比较小 的空间。类似于一般操作系统中的pc计数器,通过改变计数器的值,来执行下一条字节码的指令。相当于字节码的行号指示器,进行分支跳转或者循环,异常处理等操作。

对象的创建和查询

对象创建

1.首先确认是否完成类加载
2.分配堆内存,分配方式由垃圾回收机制决定,如果垃圾回收机制有整理(conpact)过程,堆内存会平整,分配方式采用"指针碰撞"。如果垃圾回收机制是标记清除,那么堆内存不平整,JVM需要维护一张表,记录哪些内存可用,分配方式称作"空闲列表";
3.关注内存分配时线程之间并发冲突,导致分配内存重复的问题。第一种解决方案是CAS+失败重试的方式,保证操作原子性。另一种是为每个线程预分配一块内存,称为本地线程分配缓冲TLAB,在TLAB上为每个线程分配内存。
4.new操作初始化对象,对象产生

对象查询

1.通过栈上的引用来访问堆内存的数据
2.访问方式有两种,

  • 一种是直接指针访问,该方式对象的引用存储的就是对象的地址。
  • 另一种是句柄方式,该方式在堆内维护一个句柄池,对象的引用就是句柄的地址,首先根据句柄的地址访问句柄池,句柄中包含了对象实例数据的地址和对象类型数据的地址,进而访问对象实例和对象类型的数据。
  • 这两种方式各有优势,句柄方式,对象引用不需要关注对象数据的地址,存储的稳定是句柄的地址,只需要改变句柄中的对象实例地址,垃圾回收时对象实例地址经常变更。直接指针访问的方式,优点是比较快速,缺点是引用需要经常变更

内存溢出的异常和解决办法

1.Java.lang.OutOfMemoryError: PermGen space
错误:永久代区域发生了内存溢出,发生在方法区!
原因:一是方法区中运行时常量池溢出,就是在运行过程中产生了大量的常量比如i++无限循环的产生。二是调用的类太多,导致方法区内存溢出。
解决:手动设置MaxPermSize大小(在编译器中可以设置)

2.java.lang.OutOfMemoryError: Java heap space
错误:java堆溢出。
原因:直接原因是达到了最大堆的容量。导致错误的深层次原因是,可能某些对象的生命期过长或者可能是一直产生对象,并且GC无法回收,引起的内存泄漏。
解决:手动将最大堆Xmx的size设置大一些,一般为物理内存的25%,不超过80%。减少对象持有时间过长的现象。
3.java.lang.StackOverflowError
错误:虚拟机栈和本地方法栈溢出。
原因:线程申请的栈的深度大于虚拟机允许的栈的深度;栈扩展时申请内存失败或抛出内存溢出而不是栈溢出。
解决:检查是否递归调用没有出口,或者栈帧过大或者本地变量太多。一般上代码层面的问题较为常见。如果代码层面,实属是内存不够引起的,减少线程或者使用更高配置的电脑(64位,128位等)。实在没法了,可以减小最大堆size和最大方法区size。因为最大堆,最大方法区容量,虚拟机栈,本地方法栈共同瓜分了同一进程的内存,比如windows是2G.
4.java.lang.OutOfMemoryError
解决:这个同样是内存溢出,但并没有提示什么具体错误,且heap dump很小,如果使用了NIO,就有可能是本地直接内存溢出。可以手动设置本地直接内存的大小 ,一般直接内存的大小默认与Xmx大小相同,单独设置可以设置参数 MaxDirectMemorySize。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值