JVM——Java内存区域

《深入理解Java虚拟机》学习笔记

运行时数据区域

JVM——Java内存区域_第1张图片
image

程序计数器

当前线程执行的行号指示器。==虚拟机规范中唯一没有规定OOM的区域==

虚拟机栈

  • 描述Java方法执行的内存模型
  • 每个方法都会创建一个栈帧,用来存放局部变量表、方法出口等。一个方法的执行,就对应一个栈帧的从入栈到出栈的过程
  • OOM:虚拟机栈无法申请到内存
  • StackOverFlow:栈的深度超出限制

本地方法栈

对应native方法,类似与虚拟机栈,只是针对的是native方法

方法区

存储类信息、静态变量、常量、即使编译器编译后的代码数据

存储对象、数组,垃圾回收也是主要作用域该区域

对象的创建

JVM——Java内存区域_第2张图片
image

类加载

检查常量池中能否定位到一个类的符号引用,如果没有则执行类加载过程

分配内存

  • 指针碰撞
    • 要求内存区域规整
    • 指针作为分界点,指针的一边是使用中的内存,一边是未使用的内存。
    • 分配内存的时候指针从使用中的内存向未使用的内存移动需要的距离
  • 空闲列表:
    • 可以婴童在内存区域不规整的条件下
    • 虚拟机维护一个空闲区域列表,使用内存的时候从空闲列表中取出一块区域,并更新列表

初始化

初始化为零值

设置对象头

对象的hash码,GC分代年龄等

执行init

把对象按照程序员的意愿初始化出来

对象的内存布局

对象头

  • hash码
  • 对象分代年龄
  • 锁相关指针
  • 类型指针:通过该指针确定是哪个类的实例

实例数据

对象真正存储的有效信息

对其填充

为保证对象头为8字节的整数倍,不够用对齐填充补齐

对象的访问定位

直接访问

JVM——Java内存区域_第3张图片
image

句柄访问

JVM——Java内存区域_第4张图片
image

直接访问速度更快,句柄访问更加稳定

String对象相关

String s1 = "hello"; //从常量池中找hello,如果有则执行该常量,如果没有则创建一个在指向它
String s2 = new String("hello"); //若常量池中没有hello,则先在常量池中创建,然后在堆上创建

8中基本类型的包装类大部分都实现了常量池

参考

  • 《深入理解Java虚拟机》
  • https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/%E5%8F%AF%E8%83%BD%E6%98%AF%E6%8A%8AJava%E5%86%85%E5%AD%98%E5%8C%BA%E5%9F%9F%E8%AE%B2%E7%9A%84%E6%9C%80%E6%B8%85%E6%A5%9A%E7%9A%84%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0.md

你可能感兴趣的:(JVM——Java内存区域)