`

使用SizeOf测定JVM中对象占用内存

 
阅读更多

一、前言

最近在学习JVM相关知识时突然想到个问题:

应该如何知道自己程序中创建的对象在虚拟机中到底占用了多大的内存?

另外,各种数据类型在虚拟机中各自占用多少内存呢?

就这2个问题,上网查了一些相关的资料。

关于查看对象占用内存的方法,比较常用应该算是使用Java VisualVM工具heap dump后查看对象实例所占用的内存。

本文将采用另外一种方式,使用一个开源工具SizeOf。

二、SizeOf

1、简介

项目下载地址:http://sourceforge.net/projects/sizeof/

其实就一个jar包,放到Eclipse工程路径下,添加到classpath中。

运行前添加VM参数:-javaagent:./lib/SizeOf.jar 运行即可(将jar放在lib路径下)。

2、实现原理

下载一份源代码后发现工具类只有一个SizeOf.java。

看了一下内部实现,主要使用的是JDK1.5中提供的新功能:Instrumentation。

Instrumentation介绍(源自网络):开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在JVM上的程序,甚至能够替换和修改某些类的定义。开发者就可以实现更为灵活的运行时虚拟机监控和Java类操作,这样的特性实际上提供了一种虚拟机级别支持的AOP实现方式,使得开发者无需对JDK做任何升级和改动,就可以实现某些AOP的功能了。

在SizeOf中,其实是使用Instrumentation特性getObjectSize监控JVM程序中对象的大小。

三、验证对象占用内存大小

1、规范

首先参考JVM规范相关介绍,Java中各数据类型占用内存为:

byte:1字节

boolean:1字节(待定)

short:2字节

char:2字节

int:4字节

float:4字节

long:8字节

double:8字节

java.lang.Object:8字节

ref object:对象的引用4字节

return address:4字节

2、通过SizeOf验证

环境:Windows + Sun HotSpot VM

(1)常见的类型

System.out.println("Integer: \t\t"+SizeOf.sizeOf(1));
System.out.println("Char: \t\t"+sizeOf('a'));
System.out.println("Long: \t\t"+SizeOf.sizeOf(1L));
System.out.println("Double: \t\t"+SizeOf.sizeOf(1.0D));

输出

Integer: 		16
Char: 		16
Long: 		16
Double: 		16

为什么全都是16字节呢?

原因是Java中所有类都是Object的子类,而java.lang.Object空壳对象本身占用8个字节。

System.out.println("Object: \t\t"+ SizeOf.deepSizeOf(new Object())); //8byte

另外,对象在Java HotSpot VM中都是按8字节对齐(无论32bit还是64bit),也就是说不满8字节的,填充至8字节,比如Integer原本实际占用8+4=12字节,但是需要按8字节对齐,因此就是16字节了。而Long和Double本身刚好占满16字节,不需要对齐。

(2)数组

int[] array=new int[2];
System.out.println("array:"+SizeOf.deepSizeOf(array)); //24byte

此处声明了一个包含2个int型元素的数组,计算大小为8+4*2=16字节,为什么会输出24字节呢?

原因是,每个数组都包含一个4字节的空间用来记录数组的长度。所以,实际大小为8+4*2+4=20,然后按8字节对齐为24字节。

(3)字符串

System.out.println("string: \t"+ SizeOf.deepSizeOf(new String("1")));//40byte

String对象大小分2部分计算:

a)内部有四个成员变量占用空间:

三个4个字节的int类型offset、count、hash(3x4=12字节),一个引用类型4字节(char[]数组的引用),String继承了java.lang.Object,“空壳”对象也有8个字节。 合计:12+4+8=24byte

b)char[]占用空间:

8(空壳)+4(数组长度)+2(一个字符"1"占用的空间)=14byte -> 对齐后=16byte

所以这个String的实际长度是24+16=40byte

 

结束语

以上就是通过SizeOf测定对象占用内存方法。

另外,欢迎访问我的另外一篇blog:JVM堆中对象结构 http://shensy.iteye.com/blog/1879789

分享到:
评论

相关推荐

    测定JVM中对象占用内存—SizeOf

    原项目下载地址:http://sourceforge.net/projects/sizeof/ ...1、将SizeOf.jar放到Eclipse工程路径下,添加到classpath中; 2、运行前添加VM参数:-javaagent:lib/SizeOf.jar 运行即可(将jar放在lib路径下)。

    测试java对象占用内存大小的例子

    在Java中,由于垃圾回收机制的存在,直接获取对象的内存占用并不像C++等语言那样简单。通常,我们可以使用一些工具或API来帮助我们。例如,`sun.misc.Unsafe`类(虽然非标准,但广泛使用)提供了访问内存的能力,...

    Eclipse使用SizeOf.jar工具监测内存占用

    为了验证SizeOf.jar是否正确安装并可用,可以编写一段简单的测试代码来检查特定对象的内存占用情况。例如,可以通过创建一个包含数组或集合的对象,并使用SizeOf.jar提供的方法来获取其占用的内存大小。 ### 步骤5...

    java-sizeof-0.0.4:一个查看java对象占用内存大小

    本文将深入探讨Java中的对象内存占用,以及如何使用"java-sizeof-0.0.4"工具来查看Java对象在内存中的大小。 在Java中,内存主要分为堆内存(Heap)和栈内存(Stack)。对象通常存储在堆内存中,而基本类型的变量和...

    java 通过sizeOf计算一个对象的大小

    `sizeOf`通常是指用来计算对象在内存中占用空间的一种方法。本篇文章将探讨如何通过Java来实现这样的功能,以及相关知识点。 首先,Java虚拟机(JVM)在运行时为每个对象分配内存,包括实例变量、类信息、对其他...

    dotnet 运行时获取某类型的对象占用内存大小.rar

    通过检查对象生命周期、分析长时间运行的程序的内存使用趋势,以及使用内存诊断工具,可以帮助定位潜在的内存泄漏问题。 8. **MAUI框架**: 标签中提到的MAUI(.NET Multi-platform App UI)是.NET的跨平台UI框架...

    sizeof测试字节数

    sizeof测试字节数

    浅谈Python 对象内存占用

    在Python中,对象的内存占用可以通过内置的`sys`模块中的`getsizeof()`函数进行测量。该函数接收一个对象作为参数,并返回其内存占用量(以字节为单位)。值得注意的是,该函数仅能准确测量Python内部对象的大小,并...

    不使用sizeof 判断一个数据所占的内存大小

    在C语言中,不同的数据类型根据其定义和编译器的实现,会有不同的内存占用大小。比如常见的数据类型int、float、double等,在不同的系统架构和编译环境下可能会有不同的大小。比如,在32位系统上,一个int可能占用4...

    matlab开发-sizeof

    在MATLAB编程环境中,`sizeof`是一个非常重要的函数,它用于获取MATLAB中内置数据类型所占用的内存字节数。这个知识点对于理解和优化MATLAB程序的性能、内存使用以及理解数据存储方式至关重要。下面我们将深入探讨`...

    SizeOf.jar

    SizeOf.jar就是用来解决这个问题的,它提供了一种方法来估算Java对象在内存中占用的空间。 SizeOf.jar的工作原理是通过反射API来遍历对象的所有字段,包括嵌套的对象和数组,然后计算每个字段所占的字节数。Java中...

    sizeof(结构体)和内存对齐

    sizeof(结构体)是指结构体在内存中的大小,而内存对齐是指编译器为了提高程序的效率和可移植性,对内存地址的限制和调整。 在C语言中,结构体的大小不仅取决于结构体成员的个数和类型,还取决于内存对齐的规则。在...

    C++对象内存模型.pdf

    在 C++ 中,我们可以使用 sizeof 运算符来获取对象的内存大小,并且通过 std::cout 可以输出我们所需要的各种实验数据。为此,我们可以定义宏 define 来简化我们的实验过程。 #define DisPlayTypeSize(TypeName) ...

    sizeof函数使用注意事项

    7. **模板元编程**:在C++中,`sizeof`也可以在模板元编程中使用,用于在编译时确定类型信息,这对于构建泛型代码和类型安全的库非常有用。 8. **空类大小**:一个不包含任何数据成员的类,其大小至少为1,这是为了...

    sizeof运算符的使用

    在C/C++编程语言中,`sizeof`运算符是一个非常重要的工具,用于获取任何数据类型或变量所占用的内存字节数。理解`sizeof`的使用对于优化代码、理解和预测程序内存消耗至关重要。以下是关于`sizeof`运算符的详细解释...

    sizeof 计算出实例的大小

    然而,程序员有时仍需要了解对象占用的内存大小,这通常涉及到性能优化或理解内存消耗。在这种情况下,可以采用一些间接的方式来获取类似的信息。 反射(reflection)是Java提供的一种强大工具,允许程序在运行时检查...

    sizeof求struct结构体内存大小的问题

    在C语言中,`sizeof`运算符用于计算数据类型或者变量在内存中占用的字节数。当应用于`struct`结构体时,它会返回整个结构体占据的总字节数,这涉及到内存对齐的问题。内存对齐是编译器为了提高数据访问效率而采取的...

    详细讲解sizeof的使用

    ### 详细讲解 `sizeof` 的使用 #### 一、`sizeof` 概念解析 `sizeof` 是 C 语言中的一个单目操作符,用于获取指定类型或变量的...通过对 `sizeof` 的深入理解,开发者可以更好地控制程序的内存使用,优化程序性能。

    解析C语言中的sizeof.rar

    总结来说,`sizeof`是C语言中一个强大的工具,用于获取数据类型和变量的内存占用。理解`sizeof`的使用和行为对于编写高效且跨平台的C代码至关重要。在编程时,应充分利用`sizeof`来检查和优化内存使用,避免潜在的...

    MFC源代码 SIZEOF.02

    MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 SIZEOF.02MFC源代码 ...

Global site tag (gtag.js) - Google Analytics