《深入理解java虚拟机》读书笔记(1)- JVM内存基本结构

《深入理解java虚拟机》读书笔记(1)- JVM内存基本结构

前言

面向的读者:

  • 有一定java基础
  • 想系统学习JVM基础知识
    文章目的:
  • 自己读书笔记
  • 精炼知识点,实现输入输出闭环

一、JVM运行时内存区域

需要注意的是,JVM划分了很多内存区域,这些区域都是逻辑上的。其实在物理上,他们可以是同一块区域或者不块区域。这里,我们只讨论逻辑区域。

  • 程序计数器(program counter register): 由JVM 控制,没有定义OOM,主要用来控制程序的执行。多线程情况下,还会记录线程状态。
  • 虚拟机栈(Java Virtual Machine Stack): Java 是基于stack的语言,栈是线程私有的。方法执行时,会创建一个stack frame。
  • java 堆(java heap): 对象所在的空间,也是垃圾回收的主要场所。线程共有的。
  • mataspace: 存放class,常量,即时编译缓存代码等。这里也会回收,但是一般效率不高。不过有时候也会出现溢出情况。FastJson就由一个bug,会导致这里的内存溢出。
  • 直接内存(Direct Memory)。JVM之外的一块区域,现在用到的场景就是NIO 里面,作为缓冲区。
    jvm 内存划分

二、java对象在内存中是怎样存在的

1. 对象的创建

1.1 对象创建方式

对象创建时,需要为对象分配对应的内存空间。分配空间的方式有两种

  • 指针碰撞(Bump the Pointer)
    Bump the Pointer
  • 空闲列表 (free list)
    free list

具体采用哪种分配方式需要,是更具内存空间是否连续来决定的。一般来说,带compact的垃圾收集器,会采用Bump the Pointer。不带compact的垃圾回收器,没法整理内存空间,所以只有使用free list

1.2 考虑多线程的情况

由于堆内存是线程共享的,而且对象的创建是非常平凡的,所以在并发情况下,可能出现指针错位的情况。解决这个问题,可以有两种办法

  • CAS 保证原子性
  • 本地线程分配缓冲(Thread Local Allocation Buffer, TLAB). 线程创建一块缓冲区,当然这个区域是线程独有。只有这块区域不够时,才去线程外申请新的空间。

到目前为止,对象只是有了他的内存空间,但是这个空间里面要存什么东西,还没有开始。下一步就是设置对象的头信息,调用< init>() ,调用构造函数。

2. 对象的内存布局

对象在内存中的布局

3. 怎么找到内存中的对象

  • 句柄池,对象被移动时,只改变句柄池中的指针数据,reference本身不用移动
    句柄池
  • 直接指针,速度快,内存小。
    直接指针

总结

本章主要介绍JVM的内存布局,在后面的章节,会对每一个内存进行详细讲解。另外,书中还有很多实践,相信如果对理论知识完全掌握的情况下,自己写一些case应该没有问题,本文就不做列举。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值