JAVA虚拟机
2020-04-16 08:43:16 0 举报
AI智能生成
JAVA虚拟机
作者其他创作
大纲/内容
给对象一个引用计数器,当有一处引用到它,计数器就+1,当引用失效时,计数器-1。当计数器为0时,对象将被回收。但这个算法存在一个问题:如果两个对象相互引用,不会被回收
引用计数算法
可达性分析算法
算法
垃圾收集器
JAVA虚拟机
自动内存管理
运行时数据区域
方法区
存储数据类型
被虚拟机加载的类型信息
常量
静态变量
即时编译器编译后的代码缓存
等等
与“永久代”对比
在Jdk8之前,方法区常被称为“永久代”,但事实上两者并不是等价的。可以说是永久代实现了方法区
运行时常量池
存储类的版本、字段、方法、接口等描述信息
常量池表,存放编译期生成的各种字面量与符号引用,类加载后直接存放到运行时常量池
堆
几乎所有对象实例都分配在堆里。为什么是“几乎”?随着JAVA的发展,逃逸分析技术日渐强大,栈上分配,标量替换
内存回收角度划分
新生代
老年代
永久代
Eden空间
From Survivor空间
To survivor空间
分配内存角度
所有线程共享堆内存
划分多个线程私有的分配缓冲区(Thread Local Allocation Buffer),提高效率
堆内存是否连续
物理上可以不连续
逻辑上是连续的
虚拟机栈
每个方法的执行会同步创建一个栈帧,用于存储局部变量表,操作数栈,动态连接,方法出口等信息
局部变量表中存储空间以局部变量槽来表示,其中64位长度的long和double会占用两个槽
局部变量表所需的空间在栈帧中完全确定的,这里的大小指的是槽的大小
异常
StackOverflowError
线程执行深度大于虚拟机所允许的深度时
OutOfMemoryError
线程申请栈空间失败时
如果栈空间容量可以动态扩展,当拓展时无法申请到足够的空间时
本地方法栈
与虚拟机栈相似,为使用到的本地方法服务
程序计数器
当前线程所执行的的字节码的行号指示器,它是程序控制流的指示器,分支、循环、跳转、线程恢复、异常处理等操作都是通过程序计数器来完成
如果方法在执行native方法时,程序计数器的值为空
直接内存(direct memory)
不受JAVA堆的限制,但是受到本机总内存以及处理器寻址空间的限制
运行时常量池和方法区
栈
直接内存
对象
对象所需内存大小在类加载完成后就完全确定好了
内存分配类型
指针碰撞
内存规整
垃圾收集器带空间压缩整理
Serial
ParNew
含义
内存绝对规整,分配内存仅需把指针向空闲空间方向挪动与对象大小相等的距离
空闲列表
CMS
内存分配并发处理
分配内存空间的动作进行同步处理,CAS失败重试
预先分配内存,本地线程分配缓冲,当使用完后才需同步分配
开启参数
-XX:+/-UseTLAB
内存布局
对象头
自身运行时数据
哈希码
GC分代年龄
锁状态标志
01未锁定
存储对象哈希码,对象分代年龄
00轻量级锁
指向锁记录的指针
10重量级锁
指向重量级锁的指针
11gc标记
空
01可偏向
偏向线程Id、偏向时间戳、对象分代年龄
线程都有的锁
偏向线程ID
偏向时间戳
实例数据
对象真正有效数据
加载顺序
默认:longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers,OOPs
参数:-XX:FieldsAllocationStyle
对齐填充
访问定位
句柄定位
堆中划分内存作为句柄池,包括实例数据和类型的地址
直接指针
直接指向堆中实例指针(与句柄定位对比,直接指针减少了间接访问开销)
0 条评论
回复 删除
下一页