深入理解Java虚拟机第二章Java内存区域与内存溢出异常

学习总结

为了增加记忆,把最近学习的写在博客上,总结第二章Java内存区域与内存溢出异常,第三章垃圾收集器与内存分配策略,第十二章Java内存模型与线程和第十三章线程安全与锁优化的知识点。

第二章Java内存区域与内存溢出异常

jvm把自己获得到的内存分为几个部分JVM运行时数据区
黑色的是线程共享的,红色的是线程独享的
程序计数器:

  • 作用:当前线程所执行的字节码的行号指示器,用来控制分支跳转和取下一条指令,和os中cpu的程序计数器差不多
  • 特点:每个线程都有,互相不影响。线程执行java方法时,记录的是正在执行的虚拟机字节码地址,Native方法时,这个计数器值为空(undefined),在此内存区域没有规定out of memory error

Java虚拟机栈

  • 作用:用来描述java方法执行的内存模型,方法在执行时创建栈帧,用来存储局部变量表、操作数栈、动态链接、方法出口等信息。
  • 特点:线程私有,生命周期与线程相同,有两种异常:stack over flow error和out of memory error

本地方法栈

  • 作用:用来描述Native方法执行的内存模型,在hotspot虚拟机中与虚拟机栈合二为一

Java堆

  • 作用:存放对象实例,几乎所有对象都在这里分配内存,也是垃圾回收的主要区域,分为新生代和老年代,还有Eden 、from survive和to survive空间。
  • 特点:在虚拟机启动时创建,所有线程共享

方法区

  • 作用:存储已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码

HotSpot虚拟机

  1. 对象的创建
    ①当虚拟机遇到一个new指令时,先去常量池中找类的符号引用,并检查是否已经被加载、解析和初始化,如果没有就先进行类的加载
    ②加载后虚拟机为新生对象分配内存
    ③内存分配后,虚拟机将分配到的内存空间初始化为零值
    ④虚拟机对对象进行设置,比如对象是哪个类的实例,如何找类的元数据信息,对象的哈希码、gc分代年龄等,放到对象头中。
    之后进行方法之类的java方法

  2. 对象的内存布局
    对象在内存中存储的布局分为三块区域:对象头,实例数据和对齐填充。

    对象头:包含两部分①Mark Word,用来存储对象自身运行时的信息,如哈希码,GC分代年龄等。②类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定对象是哪个类的实例。

    实例数据:代码中定义的各种类型的字段

    填充:占位用,可有可无

  3. 对象的访问定位
    Java程序通过栈上的reference数据来操作堆上的具体对象。主流的访问方式有使用句柄和直接指针两种。
    句柄方式:Java堆中划分出一块内存作为句柄池,reference存放对象的句柄地址,句柄中包含了对象实例数据和类型数据各自的具体地址信息。
    句柄访问对象
    直接指针方式:堆中需要考虑数据怎么存放类型数据的相关信息,reference中存储的就是对象地址
    直接指针方式
    优缺点对比
    句柄:好处是reference中存储的是稳定的句柄地址,对象移动时,只会改变句柄中的实例数据指针,reference本身不需要改变。
    直接指针:快,节省了一次指针定位的时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值