原文地址:点击打开链接 ,翻译有出入之处,请以原文为准
本文中,我们讨论一个问题:如何计算(或者说,估算)一个Java对象占用的内存数量?
通常,我们谈论的堆内存使用的前提是以“一般情况”为背景的。不包括下面两种情形:
- 某些情况下,JVM根本就没有把Object放入堆中。例如:原则上讲,一个小的thread-local对象存在于栈中,而不是在堆中。
- 被Object占用内存的大小依赖于Object的当前状态。例如:Object的同步锁是否生效,或者,Object是否正在被回收。
我们先来看看在堆中单个的Object长什么样子
在堆中,每个对象由四个域构成(A、B、C 和 D),下面我们逐个解释一下:
- A:对象头,占用很少的字节,表述Object当前状态的信息
- B:基本类型域占用的空间(原生域指 int、boolean、short等)
- C:引用类型域占用的空间(引用类型域指 其他对象的引用,每个引用占用4个字节)
- D:填充物占用的空间(后面说明什么是填充物)
下面我们对A、B、C 和 D 逐一解释
A:对象头
内存中,每个对象占用的总空间不仅包含对象内声明的变量所需要的空间,还包括一些额外信息,比如:对象头 和 填充物。“对象头”的作用是用来记录一个对象的实例名字、ID 和 实例状态(例如,当前实例是否“可到达”,或者当前锁的状态等等)。
在当前的JVM版本中(Hotspot),“对象头”占用的字节数如下:
- 一个普通对象,占用8 bytes
- 数组,占用 12 bytes,包含普通对象的 8 bytes + 4 bytes(数组长度)
B:基本类型
boolean、byte 占用 1 byte,char、short 占用 2 bytes,int、float 占用 4 bytes,long、double 占用 8 bytes
C:引用类型
每个引用类型占用 4 bytes
D:填充物
在Hotspot中,每个对象占用的总空间是以8的倍数计算的,对象占用总空间(对象头+声明变量)不足8的倍数时候,自动补齐。而,这些被填充的空间,我们可以称它为“填充物”。我们看下具体实例:
- 一个空对象(没有声明任何变量)占用 8 bytes -- > 对象头 占用 8 bytes
- 只声明了一个boolean类型变量的类,占用 16 bytes --> 对象头(8 bytes) + boolean (1 bytes) + 填充物(7 bytes)
- 声明了8个boolean类型变量的类,占用 16 bytes --> 对象头(8 bytes) + boolean (1 bytes) * 8
通过上面的实例,更有助于我们理解
分享到:
相关推荐
在Java编程语言中,了解一个对象占用的内存字节数对于优化内存使用和理解程序性能至关重要。本篇文章将深入探讨如何计算Java对象占用的内存字节数,以及影响这一数值的因素。 首先,Java对象在堆内存中由四个部分...
实验中创建了一个名为`Person`的对象,发现其占用32字节。这32字节通常包括:对象头(12字节,其中8字节用于Mark Word,4字节用于Klass Pointer),实例数据(假设Person类没有任何字段,因此为0字节),以及可能的...
在Java编程语言中,了解一个对象占用的内存大小对于优化程序性能、理解内存消耗以及防止内存泄漏至关重要。本文将深入探讨如何计算Java对象所占内存,并通过提供的代码示例进行详细解析。 首先,我们需要理解Java...
在Java编程语言中,了解一个对象占用的内存大小是非常重要的,尤其是在优化性能或者处理大量对象时。本示例主要探讨如何测试Java对象占用的内存大小,以便更好地理解内存使用情况。 首先,`SizeOf.java`可能是一个...
3. **填充数据(Padding)**:为了对齐,如果实例数据不足一个内存对齐单位,JVM会在对象尾部添加填充字节,确保对象大小为对齐单位的整数倍。 理解对象内存布局有助于优化程序性能,例如减少对象创建、理解和使用...
一个空的String对象占用28个字节的内存,包含了一个指向字符数组的引用、一个偏移量、一个字符的长度和一个哈希码。当字符串内容非空时,内存占用会增加,因为需要存储字符数据。例如,字符串"ab"会占用28 + 2 * 2 =...
当我们谈论“Java对象内存大小”时,我们通常指的是一个Java对象在内存中占据的空间,包括对象头、实例字段以及可能的对齐填充。这个知识点对于开发高效缓存系统尤其重要,因为缓存需要精确管理内存来最大化存储效率...
1. **Java VisualVM**:这是一个强大的Java性能分析工具,可以显示对象的大小、内存分配和垃圾回收情况。通过“对象”视图,可以观察到对象实例的大小。 2. **JOL (Java Object Layout)**:JOL是一个轻量级库,它...
在Java中,直接获取一个对象所占用的内存大小并非易事。常见的做法是在运行特定代码之前记录当前的内存状态,待代码执行完成后,触发垃圾回收机制,并再次记录内存状态。通过对比两次内存状态的变化,可以估算出代码...
在Java编程语言中,了解一个对象的内存大小是很有用的,特别是在性能调优和内存管理方面。`sizeOf`通常是指用来计算对象在内存中占用空间的一种方法。本篇文章将探讨如何通过Java来实现这样的功能,以及相关知识点。...
在Java编程语言中,计算一个对象的大小是一个相对复杂的过程,因为对象的内存布局涉及到多个因素,包括对象头、实例字段、对齐填充等。这个主题通常与性能优化和内存管理有关,尤其是在处理大规模数据结构时。这篇...
"计算对象占用内存空间ObjectSize-master.zip" 提供的工具可能是一个帮助开发者分析和估算对象在内存中占用大小的解决方案。这样的工具对于调试、性能调优以及避免内存泄漏至关重要。 在Java中,对象的内存占用不...
### Java内存对象分配过程研究 #### 一、引言 Java作为一门强大的面向对象编程语言,在实际开发过程中,对象的创建及其内存管理是至关重要的环节。深入理解对象在内存中的分配过程不仅能够帮助开发者设计出更为...
解决这些问题的方法包括但不限于调整JVM参数以增大内存分配、优化代码以减少内存占用、及时关闭不再使用的资源(如数据库连接)以及使用内存分析工具检测和修复内存泄漏。正确理解和运用Java内存机制以及异常处理...
- 创建一个简单的Java应用,使用Memcached-Java-Client 2.6.1实现用户登录信息的缓存,提高登录速度。 - 演示如何在Spring框架中配置和使用Memcached,结合Spring的AOP特性实现自动缓存管理。 通过以上内容,我们...
总之,方法区是Java内存模型中的一个重要组成部分,它负责存储类的元数据信息,包括类的字节码、静态与非静态方法、静态成员变量、常量以及字符串常量池等。通过对这些信息的高效管理和合理组织,方法区极大地提升了...
JVM内存调优是一个复杂的过程,需要根据应用程序的特性和资源需求进行调整。通常,我们需要关注垃圾收集器的性能,如新生代与老年代的占比,以及内存分配和回收的效率。同时,监控系统的CPU使用率、内存占用和GC日志...
- **垃圾回收(GC)**: Java虚拟机的垃圾回收器负责回收不再使用的对象占用的内存。 - **集合(Collection)**: Java集合框架包括List、Set、Map等接口及其实现类,如ArrayList、HashMap等。 - **多线程**: Java通过...
2. 在Java的基本数据类型中,char型采用Unicode编码方案,每个Unicode码占用2字节内存空间。这是因为Unicode编码方案使用双字节来表示每个字符。 3. 设x = 2,则表达式(x + +)/3的值是1。这是因为Java语言的运算符...
Java对象在JVM中的内存占用是一个复杂而重要的主题,它涉及到Java虚拟机的内存区域划分、对象头、实例数据以及对齐填充等多个方面。这里我们将深入探讨这些知识点,以便更好地理解和优化Java应用程序的性能。 首先...