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就在栈中为这个变量分配内存空间 ...
随机推荐
- 天翼云云电脑:IAAS基础设施带来的计算革新
本文分享自天翼云开发者社区<天翼云云电脑:IAAS基础设施带来的计算革新>,作者:不知不觉 在当今这个数字化快速发展的时代,云计算作为一种新兴的信息技术,已经逐渐成为企业和个人日常运营的重 ...
- Spring AI + DeepSeek:提升业务流程的智能推理利器
今天,我们将深入探讨如何利用DeepSeek来真正解决我们当前面临的一些问题.具体来说,今天我们仍然会将DeepSeek接入到Spring AI中进行利用.需要注意的是,虽然DeepSeek目前主要作 ...
- FLink参数pipeline.operator-chaining介绍
1.当使用flink提交一个任务,没有给算子设置并行度情况下,默认所有算子会chain在一起,整个DAG图只会显示一个算子,虽然有利于数据传输,提高程序性能,但是无法看到数据的输入和疏忽,业绩反压相关 ...
- 在 GitLab CI/CD 中使用内置的容器镜像库
配置 Docker-in-Docker Docker-in-Docker (dind) means: 你应该注册一个 Docker executor 或 Kubernetes executor 执行器 ...
- window本地部署deepseek
window本地部署deepseek 学习自[[教程]DeepSeek本地免费部署教程,丝滑不卡顿!带你解锁隐藏功能!]https://www.bilibili.com/video/BV1viFaeB ...
- STM32 DMA操作
https://blog.csdn.net/u014754841/article/details/79525637?utm_medium=distribute.pc_relevant.none-tas ...
- Typescript通用帮助类,格式化日期时间等
/** * 格式化日期选项 */ export class DateFormatOption { "M+": number;//月 "d+": number;/ ...
- JS ellipse 转 PathData
绘制Path function ellipse2path(cx, cy, rx, ry, degree) { //cx cy:圆心 //rx ry:x y 轴长 //degree:度数,顺时针方向为正 ...
- 服务器vps测试脚本大全,新云linux综合工具箱-linux加速脚本 一键硬盘挂载
服务器vps测试脚本大全 一键更换yum脚本 一键优化shh卡顿 一键更换软件源 各种linux加速 BBR原版 bbrplus 魔改plus 锐速 脚本linux加速脚本 一键硬盘挂载 一键cc防御 ...
- k8s dial tcp 127.0.0.1:6443: connect: connection refused排查流程及解决思路
前言 k8s 集群中,使用 kubelet 报错,如下: The connection to the server 127.0.0.1:6443 was refused - did you speci ...