JVM内存管理

JVM内存管理

程序要运行,就需要有数据,有了数据,自然要存储,而不同的数据有不同的存储方式,存储空间,以及管理方式。Java程序自然也不例外,因此有了JVM的内存管理。只有可以高效的分配和释放内存,程序才能更加高效的运行。

常见的数据:

  • 静态变量
  • 常量
  • 局部变量
  • 超大对象
  • 小对象
  • …等等

1、JVM内存区域划分图

在这里插入图片描述

2、程序计数器

程序计数器,记录当前正在执行的字节码的地址,通俗而言就是记录当前执行到的的字节码的行号,如果当前正在执行的是一个本地方法的话,该值为空(Undifined)。程序计数器也成为PC指针。

程序计数器的作用

Java虚拟机的多线程是通过切换CPU时间片的方式来实现的,任意时刻,一个单核处理器只能执行一个线程中的指令。为了在发生线程切换后,CPU能从正确的位置继续执行,因此需要保护现场,另外对于程序中的异常,循环,分支跳转等都需要程序计数器。程序计数器只记录所在线程的当前执行的字节码的行号,每个线程都有属于自己的程序计数器,程序计数器属于线程私有的。
在这里插入图片描述
可能的异常或者错误

因为程序计数器只记录字节码的行号,因此所占内存空间特别小,不会发生OOM和StackOverflow。(也是唯一一块不会抛出OOM的内存区域)。

2、Java虚拟机栈

Java虚拟机栈,描述Java方法执行的内存模型,方法调用时,都会创建一个栈帧,栈帧中存储方法的局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法从调用过程,就对应一个栈帧在虚拟机栈中入栈和出栈的过程。可以通过-Xss来设置虚拟机栈的大小。
主要包含以下信息:

2.1、局部变量表

局部变量表存储编译器可知的数据类型(8大基本数据类型和对象引用),因为Java是一门跨平台的语言,因此这些数据类型的大小在编译器间就是已知的,因此局部变量表的内存空间在编译期间就已经分配完毕,且在运行期间不会再改变。
这些数据类型在局部便量表中的存储空间以局部变量槽来表示,局部变量槽的大小以32bit和64bit居多,由虚拟机自身决定。
局部变量表类似于操作系统的内存,用于存储CPU执行所需要的数据。

2.2、操作数栈
操作数栈相当于一层缓存,每次执行引擎在读取数据时,都预先将局部变量表中的数据拷贝到操作数栈中。满足先进后出的原则。

2.3、可能的异常或者错误

当方法调用的栈深度超过虚拟机运行的栈深度时(没有出口的方法递归调用),就会抛出StackOverflow错误。一般而言栈的深度是可以扩展的,当扩展时无法再申请到内存时就会抛出OutOfMemroy错误。那么到底抛出哪个错误呢?
在这里插入图片描述
虚拟机栈中其实存着着两种栈,第一种是栈帧,对应着方法,每一个方法的调用都会形成栈帧,压入虚拟机栈中,遵循先进后出的原则。另一个是操作数栈,对应着操作数。

3、本地方法栈

本地方法栈的作用与Java虚拟机栈的作用基本是一致的只是,本地方法栈上执行的是Native方法,而虚拟机栈上执行的是Java方法而言。而且堆本地方法栈的使用并没有严格规定,因此有的虚拟机直接将两部分合二为一。

可能的异常或者错误

与虚拟机栈一样该区域也可能抛出StackOverflow和OOM,且原因和本地方法栈是一样的。

4、Java堆

Java堆在虚拟机启动时创建,是Java虚拟机管理的内存的最大的一块内存。在Java中几乎所有的对象和数据都在Java堆上进行内存分配。Java堆是垃圾回收器管理的主要区域,因此也成为GC堆。Java堆上存放对象实例数据,和数组,但并非所有的对象实例和数组都在堆上分配。Java堆在逻辑上是连续的,在物理地址上一般是不连续的。
由于对象生命周期不同及垃圾收集器的原因,又将堆空间分为新生代和老年代,其中新生代又分为Eden区和两个survive区,至于为何要这样划分详见JVM垃圾回收算法。

可能的异常或者错误

当堆中的对象所占内存达到最大值,这时候再创建新对象就会抛出OOM。堆可以通过-Xmx和-Xms来控制相应的大小。

虽然Java堆是线程共享的,但从内存分配的角度而言,也有内存私有的部分,在分配内存时,为了解决并发问题,为每个线程独自分配一块小空间(TLAB) 分配缓冲区,这样每个线程有自己独立的空间进行内存就不会出现并发问题。

5、元空间

在JDK8及其以后,引入了元空间的概念,取代了之前的永久代,通过-XX:MaxMetaspaceSize设置其大小,这块空间是在堆外内存上的。因为之前的永久代在堆上,这个区域会存储类信息静态变量常量等,甚至string.intern等都会进入这个区域,容易造成OOM。
在这里插入图片描述
而直接使用直接内存,会减少OOM的概率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值