通常情况下Hotspot虚拟机里Heap(堆)中的Java对象占用的内存包括:
- 基本数据类型的成员变量(primitive field),boolean/byte类型耗用1个字节,char/short类型耗用2个字节,int/float类型耗用4个字节,long/double类型耗用8个字节
- 对象类型的成员变量(reference field),每个变量一个4个字节的reference
于是对象占用的内存大小可以用下面的公式进行估算:
例如,对于下面一个Class:
class MyClass { // 8 bytes (object header) byte a; // 1 byte int c; // 4 bytes boolean d; // 1 byte long e; // 8 bytes Object f; // 4 bytes (reference) }
不考虑padding(对齐)的情况下该类的实例大约占用26(8 + 1 + 4 + 1 + 8 + 4)个字节,进行padding后将占用32个字节的空间。
注意:这里估算的内存占用大小并不包括对象类型的成员变量所占用的内存大小,这里只计算reference占用的内存大小。
一维数组的内存占用量:
在Java里数组也是对象,且数组对象的Object Header比普通对象的要多4个字节,这4个字节是用来存储数组长度用的。另外数组对象也会被Padding(补齐)。
基本数据类型的数组对象占用的内存大小可以用下面的公式进行估算:
如长度为10的int类型的数组int[10]占用的内存大小为: ceil((12 + 4*10)/8)*8 = 56
对象数组Object[]占用的内存大小可以用下面的公式进行估算:
4*m中的4表示每个Object reference占用的内存大小,4个字节;m表示数组的长度。
再例如,对于String类:
public final class String { // 8 bytes (object header) private final char value[]; // 4 bytes (reference) private final int offset; // 4 bytes private final int count; // 4 bytes private int hash; // 4 bytes }
一个包含n个字符的String对象整体(包括char[]数组)占用的内存大小为:
二维数组的内存占用量:
Java中的二维(多维)数组与C语言中的二维(多维)数组有非常大的不同。Java中的二维(多维)数组是由nested数组构成的一个级联结构,二维(多维)数组中的每一行都是一个reference指向的nested数组。
于是对于一个m*n的二维数组array[m][n],它的内存占用量包括下面两部分:
1个长度为m的外层数组占用的内存,可以表示为:ceil((12 + 4*m)/8)*8
m个长度为n的内存数组占用的内存,可以表示为:m*(ceil((12 + sizeof(nested_array_type)*n)/8)*8)
对于基本数据类型的二维数组,sizeof(nested_array_type)为对应基本数据类型的内存使用量
对于Object[][],sizeof(nested_array_type)等于4个字节,即reference的内存使用量
例如,对于int类型的二维数组int[m][n],它的内存占用量估算为:
ceil((12 + 4*m)/8)*8 + m*(ceil((12 + 4*n)/8)*8)
假设(m=1000000, n=3),则该二维数组的内存占用量为:
ceil((12 + 4*1000000)/8)*8 + 1000000*(ceil((12 + 4*3)/8)*8) = 28,000,016
结论:尽量避免长期持有(引用)大规模的二维数组对象
相关推荐
测试java对象占用内存大小的例子,可以测试常用的类型
JAVA对象所占内存大小计算例子,博文地址:http://blog.csdn.net/u012787710/article/details/53164226
java-sizeof-0.0.4:一个查看java对象占用内存大小
有效测量出 java 对象 内存 大小 可供缓存等计算
统计缓存大小(查看java对象所占的内存大小).
要更好的理解你的Java程序将会占用多大的内存需要先了解有哪些因素会影响到内存的占用。这些因素包括: ● 对象(Objects) ● 类(Classes) ● 线程(Theads) ● 本地数据结构(Native data ...
废话不多说,一起开干 1 前置知识 本次实验基于jdk8 64位以及以上版本。本机环境为jdk11 先查看一下jvm启动的默认参数,里面有2个参数值对本次实验会造成影响。 命令行: java -XX:+PrintCommandLineFlags -version ...
java中的栈(深层了解java虚拟机对对象的内存分布)
JAVA内存溢出问题总结
Java把内存划分成两种:一种是栈内存,一种是堆内存。 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过...
对象所需内存大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。根据java堆内存是否绝对规整,划分方法不同: 1)指针碰撞(Bump the Pointer): Java堆中内存绝对...
然后通过收集每次垃圾回收事件后对象之间的引用关系和对象内存大小, 计算得到集合类对象的内存影响值。接着通过修改字节码的方式获取到集合类 对象使用集合内元素的数据,计算出相应的元素使用影响值。最后...
第2章 Java对象持久化技术概述 2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 实体域对象的其他持久化模式...
java 作为现在用户最多,使用最为...纳更多的活跃对象。此外 , 评估堆栈的正确性和效率通过一个访问障碍。该实验结果 以一系列 SPECjvm2008 的基准表示出来。根据不同的标准测试得垃圾回收小效率有 2%-5% 的提升。
原项目下载地址:...使用说明: 1、将SizeOf.jar放到Eclipse工程路径下,添加到classpath中; 2、运行前添加VM参数:-javaagent:lib/SizeOf.jar 运行即可(将jar放在lib路径下)。
jmap:打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。 jconsole:一个javaGUI监视工具,可以以图表化的形式显示各种数据。并可通过远程连接监视远程的服务器VM。
Java内存与垃圾回收调优,Java内存与垃圾回收的调优是一个重要的主题,特别是在高性能和大规模的应用程序中。以下是一些关键的调优建议和步骤: 理解内存结构: Java堆是主要的内存区域,用于存储对象实例。 堆内存...
Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...
一种通用的内存池(也位于RAM区),用于存放所有的java对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当...