0%

深入理解Java虚拟机笔记

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

2.2 运行时数据区域

  • 程序计数器:
    • 当前线程所执行的字节码的行号指示器
    • 线程私有
  • Java虚拟机栈:
    • 虚拟机执行Java方法(字节码)服务
    • 栈帧:每个方法被执行,Java虚拟机都会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程
    • 线程私有
  • 本地方法栈:
    • 虚拟机使用到的本地方法服务
  • Java堆
    • 被所有线程共享
    • 存放对象实例
    • 是垃圾收集器管理的内存区域
  • 方法区
    • 被所有线程共享
  • 运行时常量池
    • 属于方法区
    • 常量不一定要在编译时放入
  • 直接内存
    • 不属于Java虚拟机运行时数据区,不在虚拟机内存
    • 只受本机内存限制

2.3 HotSpot虚拟机对象探秘

  • 创建
    • 【类加载检查】当Java虚拟机遇到一条字节码new指令时,首先将去检查这个指令的参数是否能在常量池中定位到 一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那 必须先执行相应的类加载过程
    • 【分配内存:指针碰撞/空闲列表】虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成 后便可完全确定。为对象分配空间的任务实际上便等同于把一块确定 大小的内存块从Java堆中划分出来。假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一 边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那 个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”。但如果Java堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那 就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分 配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称 为“空闲列表”
  • 对象的内存布局
    • 对象头
    • 实例数据
    • 对齐填充
  • 对象的访问定位
    • 句柄访问
    • 直接指针访问
看到这里的姐妹一看就要暴富暴美,为什么不让这一天提前一点呢ヾ(≧▽≦*)o