Java虚拟机(jdk1.8) 学习笔记 (虚拟机基础知识介绍)

Java虚拟机学习笔记第一篇 :Java虚拟机基础知识简单介绍

**jdk1.8内存划分:**堆、虚拟机栈、本地方法栈、程序计数器、本地内存(元空间、直接内存)

内存划分介绍:
堆:存放实例对象、字符串常量池
虚拟机栈:每个方法被执行时,jvm会同步创建一个栈帧,栈帧中包括局部变量表、操作数栈、动态连接、方法出口
1. 局部变量表:存储传递的方法入参和方法中定义的局部变量
2. 操作数栈:通过底层汇编指令来执行代码,完成压栈和出栈
3. 动态连接:执行运行时常量池时该栈帧所属方法的引用
4. 方法出口:方法的返回,正常和异常
本地方法栈:调用native方法时需要用本地方法栈来完成
程序计数器:是一块较小的内存空间,当前线程所执行字节码的行号指示器。循环、跳转、异常处理、线程恢复都需要这个计数器来完成。
在虚拟机的多线程中线程轮流切换、分配处理器执行时间的方式来实现,每条线程都有一个独立的程序计数器。
如果线程执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行是本地native方法,这个计数器值为空
直接内存:不是虚拟机内存,而是操作系统的内存,IO流中的数据缓冲区用的直接内存,分配和回收成本高,但读写性能高
元空间:类的元数据信息、运行时常量池

TLAB介绍
对象的快速分配策略,为了保证创建对象的时并发引起的线程安全问题,每个线程都有一个独立的TLAB,通过TLAB来分配对象

new一个对象的过程:
1、检查被new的对象是否再常量池中有相应的符号引用,如果没有,执行类加载
2、为该对象从堆中分配空间,分配空间的过程中,如果堆内存中的空间是连续的,需要用指针碰撞来找到空闲空间,用来分配新对象;如果堆内存中的空间不是连续的,找到记录空闲空间的空闲列表,来为新对象分配内存。
Java堆中的空间是否规整连续,取决于垃圾收集器是否带有空间压缩整理能力决定的。
当使用Serial、ParNew等带空间压缩整理的收集器时,系统采用的分配算法是指针碰撞。
当使用cms这种基于清除算法的收集器时,采用较为负责的空闲列表来分配
3、对象创建在虚拟机中是非常频繁的行为,即使仅仅修改一个指针所指向的位置,在并发情况下也并不是线程安全的,可能会出现正在给对象A分配内存,还没来得及修改指针指向,对象B又使用了原来的指针,会发生线程安全问题。Jvm底层使用cas配上重试的方式保证更新操作的原子性
4、将对象除对象头外初始化为零值,如果使用TLAB,这一项工作可以在初始化TLAB时进行分配
5、Jvm对对象实例对应的类、类的元数据信息、对象的哈希码、对象的GC分代年龄进行初始化

对象的内存布局:对象头、实例数据、对齐填充

对象头存储内容:
对象哈希码、对象分代年龄,标志位01,状态:未锁定
指向锁记录的指针,标志位00,状态:轻量级锁定
指向重量级锁的指针,标志位10,状态:重量级锁
空,不需要记录信息,标记为11,GC标记
偏向锁线程ID,偏向时间戳,对象分代年龄,标志位:01,状态:可偏向

对象的访问定位:
访问堆中对象的具体位置,有两种访问方式,句柄和直接指针。
如果使用句柄访问,在堆中会划分出一块空间来分配句柄池,句柄中包含对象的实例数据的具体地址信息,然后reference存储的是句柄的位置,如果对象进行移动,不需要修改refernce,只需要修改句柄池中的信息
直接指针是reference中存储对象实例数据的指针,可以直接指向对象实例数据
Jvm底层用的是直接指针的方式来作为对象的访问定位

各位同学注意:第一篇笔记如果有错误的地方欢迎指正,有不够详细的地方可以查看书籍或网络资料,欢迎讨论。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小武的Java笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值