JVM内存管理机制总结

目录

  1. 概述
  2. 运行时数据区域
    2.1.程序计数器
    2.2.Java虚拟机栈
    2.3.本地方法栈
    2.4.堆
    2.5.方法区
    2.6.运行时常量池
  3. 对象创建过程

1.概述

众所周知,Java虚拟机会自动管理内存资源,在开发过程中不易出现内存泄漏或内存溢出问题。首先,我们先来了解一下什么是运行时数据区域,Java程序执行时,会先将.java源文件通过编译器编译为字节码文件 .class文件。然后由JVM的类加载器加载各个类的字节码文件,最后由执行引擎执行,在这整个过程中产生运行时数据区域。

2.运行时数据区域

JVM会将所管理的内存分为几个运行时数据区域

在这里插入图片描述

  • 程序计数器 : 用于指示当前线程所执行字节码的行号,属于线程私有数据区。
    如果当前线程正在执行一个Java方法,则计数器记录当前正在执行字节码指令地址。
    如果执行的是一个Native方法,则为空。
    注意: 程序计数器是Java虚拟机规范中唯一没有规定任何OutOfMemoryError情况的区域。

  • Java虚拟机栈 : 主要存储局部变量表,操作数栈,动态连接,方法出口信息, 线程私有
    这里的本地变量存放编译期可知的各种基本类型数据(int , boolean , byte , char , short , float , long , double)、对象引用,在编译期分配所需空间。
    注意:当线程请求深度大于虚拟机栈最大深度时,将抛出StackOverflowError,如果虚拟机栈可动态扩展,若扩展时无法请求到足够的内存,将抛出OutOfMemoryError

  • 本地方法栈: 线程私有,抛出异常情况与虚拟机栈一样。

  • Java堆: 存储所有实例,数组的数据区域,所有线程共享
    堆是内存管理中空间最大的一块区域,也是垃圾收集器管理的主要区域。Java堆在物理上可以为不连续的,只需保证逻辑上连续即可。
    注意:当堆没有内存完成实例分配,并且无法在扩展时,将抛出OOM

  • 方法区: 存储被虚拟机加载的类信息,常量,静态变量,线程共享

  • 运行时常量池: 属于方法区的一部分,存放编译期生成的各种字面量和符号引用。
    注意:当常量池无法再申请到空间时,将抛出OOM

3.对象创建过程
1)当虚拟机执行到new指令时,首先会检查该类是否已被加载、解析和初始化过。如果未加载,先执行类加载过程。
2)类加载完毕后,接下来进行实例对象内存分配。分配方式根据Java堆内存是否规整分为两种:

  • 指针碰撞:堆内存规整,只将已使用和空闲内存各放一边,在两者中间分界点放置指示器,每次需要分配空间时就将指示器向空闲内存那边移动。
  • 空闲列表:堆内存不规整时,虚拟机维护一个列表,记录着哪些内存块空闲,分配时将足够的内存空间划分给实例对象,并更新列表。

3)内存分配完成后,虚拟机将分配到的内存都初始化零值,设置对象头信息(哪个类的实例、如何找到类的元数据信息,对象哈希码,GC分代年龄等)
4)上述内容执行完之后,紧接着会执行方法,把对象实例数据初始化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值