JVM

Java内存区域与内存溢出异常

运行时数据区域

  • 概览
  • 程序计数器
    如果线程正在执行的是一个java方法,那么PC对应的是虚拟机字节码指令的地址; 如果正在执行的是本地(Native)方法,PC值为空
  • 虚拟机栈
    虚拟机栈中放置栈帧,一个栈帧对应一个方法调用!栈帧存放以下内容:局部变量表、操作数栈、动态链接、返回地址等
  • 本地方法栈
    与虚拟机栈类似,不过存放的是本地方法对应的栈帧,此时PC值为空
  • Java堆
    1.所有线程共线Java堆
    2.Java堆用于存储对象的实例
    3.Java对可以处于物理上不连续的内存空间,但是逻辑上是连续的
    4.堆中可以划分出多个线程私有的分配缓冲区(TLAB, Thread Local Allocation Buffer),提升对象分配时的效率(私有缓冲区满时才才在公共缓冲区分配,减少同步开销)
  • 方法区
    1.方法区也是线程共享的
    2.方法区存储:类(型)信息、常量(常量池)、静态变量、代码缓存等数据
  • 直接内存
    1.直接内存并不是虚拟机运行时数据区域的一部分
    2.NIO可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作,从而避免了在Java堆和Native堆之间来回复制数据
    3.JVM的所有内存大小并不等于物理内存大小,JVM各数据区大小可设置

关于虚拟机中对象

  • 对象的创建过程
    类加载 => 分配内存 => 初始化为0 => 写对象头 => 执行构造方法
  • 对象的内存布局
    对象在堆内存中可分为三个部分 => 对象头、实例数据、对齐填充
    1.对象头:包括 a.对象的运行时数据(Mark Word):哈希码、GC分代年龄、锁状态…这部分数据长度占32bit或者54bit; b.类型指针,即对象指向它的类型元数据的指针,jvm通过该指针确定对象是哪个类的实例
    2.实例数据:主要是对象的各字段的具体内容(包括继承所得的)
    3.对齐填充:填充以满足“对象起始地址必须是8字节的整数倍”这一要求
  • 对象的访问定位
    Java程序通过栈上的reference数据来操作堆上的具体对象
    reference可以是直接指针(直接指向资源)、也可以是句柄(指向资源的索引),如图所示:

    注:1.“到对象类型数据的指针”实际上就是对象头中的内容; 2.直接指针访存少; 3.句柄的优势在于reference数据中存放的句柄地址稳定,对象移动时只需修改句柄中的指针

类文件结构

无关性

  • 平台无关性
    一次编写,到处运行,与操作系统无关 => 字节码构成平台无关性的基石
  • 语言无关性
    java虚拟机不仅可以运行java语言,还有其他语言比如:Kotlin、Scala也可运行在jvm之上 => 虚拟机和字节码格式可以保证平台无关性,只要其他语言可翻译成字节码格式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值