jvm 运行时数据区/对象

深入理解jvm的第二版(基于jdk1.7),一定要看下第三版
注意规范和实现的差距,规范没有的,实现可以有,规范定义的,实现的方式也未必是死板的一对一

jvm规范定义了6个运行时数据区:pc,jvm栈,本地方法栈,堆,方法区,运行时常量池
在这里插入图片描述

jvm栈(局部变量表编译期大小确定,stackoverflow:栈深度太大超-Xss,oom:申请不到内存,比如线程太多了)
native方法栈(sof和oom)
pc(当前字节码指令行号,native方法为空,无oom)
堆(对象,数组,新生代(Eden,from/to survivior)老年代,-Xms初始 -Xmx最大,经常这两个配一样大避免堆动态扩展,内存抖动)
方法区(静态变量,类信息,常量,oom,hotspot以前即1.6用永久代实现 -XX:PermSize -XX:MaxPermSize)

运行时常量池(属于方法区,Class文件(静态)常量池:字面量(常量的值和字符串,比如变量名就可以是一个字符串)和符号引用 运行时常量池:字面量和符号引用和直接引用 动态性:运行时添加常量如String.intern() ,oom)
字符串常量池(属于运行时常量池):StringTable(hashtable实现) 存储指向String对象的索引,1.7普通String和常量池字符串并无差别,仅仅是多了StringTable的指向

常量:值不变(final)的变量
jvm规范,逻辑概念:堆,方法区
hotspot,物理概念:堆,永久代/元空间
运行时常量池永远都属于方法区(因为在概念定义里常量在方法区内),但是方法区在实现上永久代-永久代+堆-元空间+堆
移除永久代:1.7把常量池和静态变量放入了堆中(譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap),永久代就很轻了,1.8永久代替换为元空间

code cache(jit):规范未定义
直接内存 (ByteBuffer.allocateDirect() 返回的DirectByteBuffer去操纵,非jvm进程内存,性能不错(避免在java堆和native堆来回复制数据),oom)

对象:内存分配:指针碰撞(垃圾收集器带compact功能,保证堆内存规整) 空闲列表(在空闲内存列表中找一块分配)
多线程同时分配内存,为保证线程安全,两种方案:1 cas加失败重试 2 每个线程在自己的TLAB里分配
内存初始化为零值,调用init方法(invokespecial)
对象头 Mark Word(32/64bit 记录hashcode,gc分代年龄,锁标志…),类型指针(指向方法区类型数据,不一定有,hotspot有),若为数组记录长度
句柄访问:对象移动(GC)不用改变reference
在这里插入图片描述

直接指针:更快,少一次指针定位,hotspot使用,对象头放类型指针
在这里插入图片描述

实例数据
对齐填充,保证对象大小为8字节倍数,保证对象起始地址为8字节倍数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值