代码编织梦想

HotSpot VM 在 Java 堆中的对象分配、布局、访问的全过程;

1. 对象的创建

在语言层面 new 一个对象(数组和 Class 对象例外),对应在 JVM 中是一条字节码 new 指令,JVM 会首先检查这个指令参数是否可以通过常量池定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析、初始化;若否,必须先执行相应加载过程;待类加载检查通过,JVM 则为新生对象分配内存;

分配内存的两种方式

  • 指针碰撞(Bump The Pointer),假设 Java Heap 中内存绝对规整,所有使用过的内存被放到一边,空闲内存放到另一边,中间以一个指针指向分界点;内存分配仅仅是把指针向空闲空间挪动一段与对象大小相等的距离,这种分配方式被称为指针碰撞;简单而高效;Java Heap 的内存并不是规整的,无法简单实用指针碰撞的方式进行内存分配,需要 GC 具备压缩整理(Compact)的能力(Serial、ParNew 等);

  • 空闲列表(Free List),JVM 维护一个记录着所有可用内存块信息的列表,内存分配就是从列表中一块足够大的空间为对象划分同等大小的内存,并更新空闲列表,这种分配内存的方式即空闲列表;基于清理(Sweep)算法(CMS)的 GC 理论上只能通过空闲列表进行内存分配(实际可以通过从空闲列表拿大块空间作为缓冲区的方式进行指针碰撞分配,Linear Allocation Buffer);

解决并发情况下线程安全的两种方式

  • 同步处理,采用 CAS 和失败重试的方式保障更新的原子性;
  • 本地线程分配缓冲(Thread Local Allocation Buffer,TLAB,-XX:+/-UseTLAB 启停),每个线程在 JVM Heap 预先分配一小块内存,哪个线程需要分配内存,就使用哪个 TLAB;分配新的 TLAB 才需要同步锁;

对象内存初始化

内存分配完成后,JVM 将分配到的内存空间都初始化为零值(使用 TLAB 则提前至 TLAB 分配时);这保障对象的实例字段在代码中可以不赋值就拥有其数据类型对应的零值;

对象头设置

根据 JVM 当前运行状态的不同(如是否启用偏向锁等),将一些信息(如:对象的类型指针、对象的 HashCode、对象的 GC 分代年龄等)存放到对象的对象头(Object Header);

对象初始化

字节码 new 指令后一般跟随一个 invokespecial 指令(Java Compiler 会将 new 关键字编译成这两条字节码指令,但也存在其他生成方式不含 invokespecial),用于执行 <init>() 方法(构造函数、静态代码块);

2. 对象的内存布局

对象的内存布局分为三部分:对象头(Object Header)、实例数据(Instance Data)、对齐填充(Padding);

对象头

  • Mark Word,存放对象自身运行时数据,如 HashCode、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向实践戳等;
  • 类型指针,指向对象的类型元数据的指针(并非所有 JVM 实现都会在对象上保留类型指针);

实例数据

存储程序代码中所定义的各类型的字段内容(自身定义的、从父类继承的);存储顺序受 JVM 分配策略参数(-XX:FieldsAllocationStyle)和字段在源码中定义顺序影响,默认分配顺序:longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers,OOPs),等宽字段分配在一起,父类变量在子类变量之前,子类中窄字段可以插入父类变量的空隙(需要开启 +XX:CompactFileds=true,默认是开启的);

对象填充

起占位符的作用(HotSopt VM 自动内存管理要求对象的大小必须是 8 字节的整数倍,对象实例数据部分未对齐时,通过对齐填充补全),非必然存在,无特殊含义;

3. 对象的反问定位

Java 程序通过 Stack 上的 reference 数据操作 Heap 上的具体对象;通过 reference 访问实际对象的方式主要分使用句柄直接指针两种,具体则由 VM 的实现而定;

使用句柄

栈上 reference 指向句柄(存储句柄地址);Java 堆中有一块内存将作为句柄池,专用于存储句柄;而句柄中包含对象实例数据和类型数据的地址信息;

reference 中存储的是稳定句柄地址,对象被移动(GC)时只会改变句柄中的实例数据指针,reference 无效修改;

直接指针

栈上 reference 指向对象(存储对象地址),访问对象本身不需多一次间接访问的开销,速度快(HotSpot 的主流方式);

from: 《深入理解 Java 虚拟机》周志明

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ChaoMing_H/article/details/128750049

jvm内存管理_陈一乐乐乐的博客-爱代码爱编程

JVM内存管理 原文:Java Memory Management for Java Virtual Machine (JVM) by Justin Gesso. June 2, 2017 翻译:陈同学 欢迎访问译

深入理解java虚拟机(一)——jvm内存结构-爱代码爱编程

说明:深入理解Java虚拟机系列是对《深入理解Java虚拟机——JVM高级特性与最佳实践》第二版一书的总结与概要 1 什么是jvm JVM(Java Virtual Machine)是Java程序运行的平台,负责执行Ja

Java笔记-----(4)JVM内存机制-爱代码爱编程

Java笔记-----(4)JVM内存机制 (1)JVM中的内存划分(重点掌握)(1.1) 方法区① 方法区和永久代的关系② 常用参数③ 为什么要使用元空间代替永久代?(1.2) 堆内存① JDK1.7的堆内存模型② JDK1.8的堆内存模型(1.3) 虚拟机栈(栈内存)(1.4) 程序计数器(1.5) 本地方法栈(1.6) 运行时常量池(1.7)

openjdk 是什么vm_什么准时!! OpenJDK HotSpot VM的剖析-爱代码爱编程

openjdk 是什么vm 重要要点 应用程序可以选择适当的JIT编译器来产生接近机器级别的性能优化。 分层编译包含五个级别的编译。 分层编译可提供出色的启动性能,并指导进一步编译级别以提供高性能优化。 JVM开关提供有关JIT编译的诊断信息。 诸如本征和向量化之类的优化进一步提高了性能。 OpenJDK HotSpo

「抄底 Android 内存优化 3」 —— JVM 内存管理-爱代码爱编程

Android 高手核心知识点笔记(不断更新中🔥)点击查看 PS:各位童鞋不要忘记给我 star 一波哦~~ 系列目录: 「抄底 Android 内存优化 1」—— 虚拟内存「抄底 Android 内存优化 2」 —— Linux 内存管理「抄底 Android 内存优化 3」 —— JVM 内存管理 「抄底 Android 内存优化 4」 ——

《java性能优化权威指南》---- 第3章:JVM概览(3.3 HotSpot VM垃圾收集器)-爱代码爱编程

文章目录 三、HotSpot VM垃圾收集器1、分代垃圾收集2、新生代3、快速内存分配4、垃圾收集器5、Serial垃圾收集器6、Parallel收集器7、CMS(Concurrent Mark-Sweep)收集器8、G1(Garbage-First)收集器9、垃圾收集器比较10、应用程序对垃圾收集器的影响 三、HotSpot VM垃圾收集器

详解 JVM 内存分配和垃圾回收算法-爱代码爱编程

目录 1. JVM 内存分配与回收1.1. 概要1.2. 堆内存常见的分配策略1.3. GC简介2. 如何判断一个对象死亡2.1. 引用计数法2.2. 可达性分析算法2.3. 如何判断一个常量是废弃常量2.4. 如何判断一个类是无用的类3. 引用3.1. 强引用(StrongReference)3.2. 软引用(SoftReference)3.3.

JVM内存以及常用工具的详细讲解-刘宇-爱代码爱编程

JVM内存以及常用工具的详细讲解-刘宇 一、JVM内存结构介绍1.1、JVM内存结构1.2、程序计数器1.3、Java 虚拟机栈1.4、本地方法栈1.5、Java 堆1.6、方法区二、引用访问对象的两种方式2.1、句柄模式2.2、指针模式(HotSpot VM使用的就是这个模式)2.3、二者区别三、堆中存储对象的过程3.1、new关键字创建对象的3

jvm(四)——JVM自带内存分析工具详解-爱代码爱编程

在进行java程序问题定位时,内存问题定位是很关键的一招。jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole、大名鼎鼎的VisualVM,IBM的Memory Analyzer等等,但是在生产环境出现问题的时候,工具的使用会有所限制。所有的工具几乎都是依赖于jdk的接口和底层的这

jvm内存dump原理与在线分析实战_java手术刀的博客-爱代码爱编程

1.前言   当前我们微服务容器化部署JVM 实例很多,常常需要进行JVM heap dump analysis,为了提升JVM 问题排查效率,得物技术保障团队研究了JVM内存Dump 原理与设计开发了JVM 内存在线分析。 常见的JVM  heap dump analysis 工具如: MAT,JProfile,最常用的功能是大对象分析。功能上本地

jvm内存监控及调优分析_monitoring 展示的内存是jvm的什么内存-爱代码爱编程

一、内存监控背景 在做JVM内存分析前,需要堆JVM内存及垃圾回收算法和垃圾回收器有一定了解,具体可以参考我之前的一篇文章:常见的垃圾回收器及垃圾回收算法 1.1、为什么要做内存监控 我们在做开发的时候不可避免的会遇到一些问题,诸如下面这些问题: 生产环境发生了内存溢出该如何处理?生产环境应该给服务器分配多少内存合适?如何对垃圾回收器的性能进行调优

利用jconsole工具监控java程序内存和jvm_jconsole查看哪个对象占用内存-爱代码爱编程

项目部署成功后时间过不多久内存就撑爆了,所以需要检测工具来监控项目内存情况。 项目内存爆满 docker容器直接挂掉。启动命令上也加上了内存溢出生成dump日志。 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/dump.log 解决问题思路大致有两种 (个人分析) 1.排查问题基本都是