Java 里的对象在虚拟机里面是怎么存储的?
Java 中的对象在虚拟机里的存储
在 Java 中,对象在虚拟机中的存储方式取决于 JVM 内存模型,主要存储在 堆(Heap) 中。对象的内存布局和管理方式会影响对象的创建、访问和销毁。下面详细解释对象在 JVM 中的存储结构。
1. 对象在堆中的存储
Java 中的对象通常存储在 堆内存 中。堆内存是 Java 内存模型中的一块区域,专门用于存储对象实例。
对象存储结构
在 JVM 中,所有对象都由 对象头 和 实例数据 组成。对象的内存分配可以细分为以下几个部分:
对象头(Object Header)
- Mark Word:存储与对象相关的信息,包括哈希码(hashCode)、GC 分代年龄、锁信息等。在不同的 JVM 实现中,Mark Word 的内容会有所不同。它是一个变长的结构,具体长度根据 JVM 的实现而异(例如在 HotSpot 中通常为 32 位或 64 位)。
- Class Pointer:指向对象所属类的元数据(如 Class 对象),即对象的类型信息。每个对象都有指向其类的指针,JVM 通过该指针来识别对象的类型。
实例数据(Instance Data)
- 这部分存储了对象的字段(成员变量),包括基本类型字段和引用类型字段。对于 引用类型字段,这部分存储的是引用地址,而不是对象本身。
对齐填充(Padding)
- JVM 采用字节对齐(memory alignment)来优化内存访问,因此对象的内存布局会根据平台和 JVM 的实现要求进行对齐,填充的空字节不会用于存储数据。
2. 对象的内存分配和访问
对象的内存分配
- 堆中的分配:Java 对象在堆中通过调用
new关键字进行分配。在对象创建时,JVM 会根据对象类型的大小进行内存分配。 - 对象引用:对象存储在堆中,但引用对象的变量通常存储在栈中。当方法调用栈中创建一个对象时,该对象的引用会存储在栈中,而对象本身则位于堆中。
对象的内存访问
- JVM 通过对象的 Class Pointer 来查找对象所属的类元数据,然后通过对象的实例数据来访问对象的成员变量。
3. JVM 对象存储的优化
对象内存压缩
- 在某些情况下,JVM 会对对象的存储进行压缩,以减少内存占用。例如, Compressed Oops(Compressed Object Pointers)技术允许在 64 位系统上压缩对象引用,减少内存消耗。
对象共享和池化
- Java 采用 对象池 技术,某些对象可以复用而不是每次都重新创建。例如,字符串常量池就是一个典型的优化,避免了重复创建相同内容的字符串对象。
逃逸分析和栈上分配
- JVM 的 逃逸分析 可以在编译时分析对象是否会被方法外部引用。如果一个对象只在方法内部使用,并且不会被外部引用,JVM 可能将该对象分配到栈上,而不是堆中,减少了垃圾回收的负担。
4. 垃圾回收与对象生命周期
- 堆管理:对象在堆中的生命周期由垃圾回收器(GC)管理。堆内存分为 年轻代 和 老年代,新创建的对象通常存放在年轻代,经过多次 GC 后,长时间存活的对象会晋升到老年代。
- 垃圾回收:当对象没有任何引用时,它就变成了垃圾对象,GC 会回收这些无用对象,释放内存。垃圾回收的过程主要发生在堆内存中。
5. 总结
在 JVM 中,Java 对象的存储包括以下几个主要方面:
- 对象头:存储对象的元信息(如哈希码、GC 标志等)和指向对象类型的指针。
- 实例数据:存储对象的成员变量,包括基本类型和引用类型。
- 堆内存:对象通常存储在堆内存中,JVM 通过堆来管理对象的内存分配与回收。
- JVM 优化:包括对象内存压缩、对象池化、逃逸分析等技术。
- 垃圾回收:堆内存中的对象生命周期由垃圾回收器管理,经过多次 GC 后对不再使用的对象进行回收。
这些存储和优化机制可以确保 Java 程序在内存管理上的高效性和灵活性。
Java 里的对象在虚拟机里面是怎么存储的?的更多相关文章
- Java并发编程(六):Java里实现对象安全发布的四种方式
接上篇,首先要了解什么是对象的发布与逸出? Java里安全发布对象的四种方法1.单例(注意懒汉和饿汉的区别)2.静态属性,注意类里的静态域和静态代码块的顺序有要求3.枚举4.final
- 【java虚拟机系列】java中类与对象的加载顺序
首先了解一下Java虚拟机初始化的原理. JVM通过加装.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.类型的生命周期如下图所示: 装载和连接必须在初始化之前就要完成. 类 ...
- 关于Java 里的String和对象
之前老师在课堂上讲过关于Java的引用,但是很遗憾,木有认真听啊,所以就在学习Java的过程中迷惑迷惑...最近好像明白一点Java的引用是怎么回事了.以下仅是我个人的理解,如果不对,还请不吝赐教. ...
- [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Java多线程基础——对象及变量并发访问
在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...
- java里的static和final
本节介绍JAVA里static和final的作用和使用方法以及一些需要注意的问题. 一.static static表示"全局"或"静态",用来修饰成员变量和成员 ...
- Java类和对象初始化
类的生命周期: Java类的初始化: 本阶段负责为类变量赋正确的初始值.(类变量即静态变量) Java编译器把所有的类变量初始化语句和静态初始化器通通收集到<clinit>方法中,该方法只 ...
- (转)Java里的堆(heap)栈(stack)和方法区(method)(精华帖,多读读)
[color=red][/color]<一> 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收. 引用数据类型,需要用new来创建,既在栈 ...
- JAVA 文件编译执行与虚拟机(JVM)简单介绍
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 ...
- 深度剖析Java变量栈&对象堆
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
随机推荐
- ctfshow--web9 md5二进制格加密的绕过
dirsearch 扫到robots文件 查看一下 发现有个index.phps文件 访问这个index.phps,可以下载下来 我们来审计一下这里的代码 <?php $flag="& ...
- ADC温敏电阻测温
一.ADC采样电路 使用热敏电阻与连续逼近型寄存器 (SAR) 模数转换器 (ADC) 直接监测温度的电路.温度检测电路使用负温度系数 (NTC) 热敏电阻与电阻串联构成分压器. 参考电压:VCC 分 ...
- 为Delphi配置多套环境
假设我们使用Delphi6开发了一个投资系统,在开发过程中我们使用了indy控件.到目前为止投资系统已经发了若干个版本,如投资系统1.0.投资系统1.2.投资系统1.5.投资系统2.0.投资系统2.3 ...
- 以数字守护汉字!天翼云TeleDB数据库获GB 18030最高级别认证!
近日,由工信部电子工业标准化研究院主办的GB 18030<信息技术 中文编码字符集>应用推广大会暨"汉字守护计划"成果发布会召开,工信部信发司.中央网信办信息化局.教育 ...
- 修改本机host文件后,浏览器访问还是旧的网址
一.修改本机host文件后也会遇到修改hosts不生效的情况,而且有时生效,有时不生效情况 1.DNS缓存机制 一条域名的DNS记录会在本地有两种缓存,浏览器缓存和操作系统(OS)缓存.在浏览器中访问 ...
- Atcoder ABC388F Dangerous Sugoroku 题解 [ 蓝 ] [ 矩阵加速 ] [ 状压矩乘 ] [ 模拟 ]
Dangerous Sugoroku:赛时写了矩乘 T 飞了,受到 sunkuangzheng 大佬的启发才知道要状压矩乘. 暴力矩乘思路 直接像过河那样写模拟细节非常多,于是考虑像美食家一样的思路, ...
- 创建Linux iscsi target存储
配置targetcli 创建存储对象 创建块存储对象 cd /backstores/block \ create block1 dev=/dev/ ...
- flutter-原生路由传自定义对象
自定义对象 1 class Dk { 2 int id; 3 String title; 4 String address; 5 String ww; 6 String account; 7 } 传值 ...
- [BZOJ4771] 七彩树 题解
好题,又学两个思路. 先把问题变简单一点,去掉深度限制,那么有两种做法: 经典的前驱后继转化到二维数点. 颜色相同的点按 \(dfs\) 序排序,每个点 \(+1\),相邻两点 \(lca-1\).转 ...
- 盘点10个.NetCore实用的开源框架项目
连续分享.Net开源项目快3个月了,今天我们一起梳理下10个,比较受到大家欢迎的.NetCore开源框架项目. 更多开源项目,可以查看我创建的,.Net开源项目榜单! 一个专注收集.Net开源项目的榜 ...