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

1.程序计数器:线程私有;记录线程执行字节码行号;如果执行Java方法计数器值为正在执行的虚拟机字节码执行地址,native方法值为空
2.JVM栈:线程私有;OOM、SOF;栈帧存储局部变量表(编译期可知的基本数据类型、对象引用、returnAddress类型)、操作数栈、动态链接、方法出口等;为Java方法服务;方法执行过程就是栈帧从入栈到出栈的过程
局部变量空间(Slot):long/double占两个,其他类型占一个
3.本地方法栈:线程私有;OOM、SOF;为native服务的JVM栈
4.Java堆:线程共享;OOM;对象、数组
5.方法区:线程共享;OOM;运行时常量池(编译期可知的字面量和符号引用,intern方法可以将新常量放入池中)、静态变量、类信息(名称、访问修饰符、字段描述、方法描述等)
6.直接内存:OOM;不属于JVM运行时数据区,默认与Xmx大小一样,可以通过-XX:MaxDirectMemorySize指定;NIO可以使用native函数库直接分配堆外内存,然后通过一个Java堆中的DirectByteBuffer对象引用该内存进行操作;unsave.allocateMemory(1M)分配直接内存
7.对象创建
类加载:JVM遇到new指令会检查执行参数是否能在常量池定位到一个类的符号引用,并且检查该类是否已加载,没有则要首先加载
内存分配:指针碰撞(内存连续)、空闲列表(内存散列),使用哪种方式分配内存取决于使用的垃圾收集器是否采用Compact过程;原子性保证,JVM采用CAS加失败重试机制,另一种是把内存分配的动作按照线程划分到不同的空间中,每个线程在Java堆中预先分配一小块内存称为本地线程分配缓冲(TLAB),这样只需要在TLAB用完分配新的时才需要同步锁定,-XX:+/-UseTLAB设置是否使用TLAB机制
初始化:JVM将分配的内存初始化为零值(除对象头)
设置对象头:对象哈希码、GC分代年龄、哪个类实例、如何找到类元数据信息等
Java初始化:java代码初始化对象
8.对象内存布局:对象头、实例数据、对齐填充
对象头:对象自身运行时数据(MarkWord,哈希码、GC年龄、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳)、类型指针(确定对象是哪个类实例),如果对象是Java数组还必须有一块记录数组长度的数据
实例数据:对象真正有效信息,程序代码中定义的各种类型字段内容,包括父类和子类的;存储顺序受到JVM分配策略参数和字段在源码中的顺序影响;默认l/d、i、s/c、b/b、oops
对齐填充:非必须
9.对象访问定位
句柄:Java堆中设置句柄池,栈中reference存储的是句柄地址,句柄指向对象实例数据(堆)和类型数据(方法区);最大优势是对象被移动时(如GC)只改变句柄中实例数据指针,不改变reference
直接指针:栈中reference存储的是对象实例数据,实例数据指向类型数据;最大优势是少一次指针定位,速度更快;HotSpot默认
10.异常:堆OOM、栈OOM、栈SOF、常量池OOM、方法区OOM、本地内存OOM
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值