我们讨论的是java heap中对象所占内存。
1.基本类型内存占用
类型 | 占用字节数 |
boolean | 1 |
byte | 1 |
char | 2 |
short | 2 |
int | 4 |
float | 4 |
long | 8 |
double | 8 |
2.对象所占内存由以下部分组成
- object header, 8 byte
- 基本类型,见第1节的表格
- 引用类型,都为4 byte
- padding,如果最后加起来结果不是8的整数倍,要补足到8的整数倍。
举例:
例1)一个空Object占8 byte
例2)
- class A {
- byte a;
- int b;
- boolean c;
- long d;
- Object e;
- }
class A { byte a; int b; boolean c; long d; Object e; }
8 (object header)
+ 1 (a)
+ 4 (b)
+ 1 (c)
+ 8 (d)
+ 4 (e) (引用类型)
= 26
然后要补足到8的倍数,所以结果是32 byte
3.数组
数组是一个特殊的对象,object header需要12 byte,额外的4 byte记录数组的长度)
3.1 一维数组
例3) int[10]
12 (object header)
+ 10 * 4
= 52
然后要补足到8的倍数,所以结果是56
3.2 二维数组
例4) int[10][10]
不可以想当然的认为是10*10*4=400
二维数组是数组的数组,所以这个对象其实只有10个元素,然后每个元素里面都有各自的10个元素
首先计算外围的元素
12+10*4 (注意此处的4只是引用,不是真实的int)=52->56
然后计算里面的元素
每个元素都是一个数组,所以都需要12 byte的header,再加真实的int占用
12+10*4 (注意此处的4计算的是int)=52->56 *10=560
结果=560+56=616
3.3 多维数组
可按二维数组计算方式递归计算
4.工具
可以用classmexer来计算内存使用量
4.1 在上述页面下载classmexer0.0.3
4.2 写一段代码测试
- package memory;
- import com.javamex.classmexer.MemoryUtil;
- class A {
- byte a;
- int b;
- boolean c;
- long d;
- Object e;
- }
- //-javaagent:classmexer.jar
- public class ClassMexerTest {
- public static void main(String[] args) {
- A a = new A();
- long byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(a);
- System.out.println("MemoryUsage of A =" + byteArrayMemoryUsage);
- int[] i1 = new int[10];
- byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i1);
- System.out.println("MemoryUsage of int[10] =" + byteArrayMemoryUsage);
- int[][] i2 = new int[10][10];
- byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i2);
- System.out.println("MemoryUsage of int[10][10] =" + byteArrayMemoryUsage);
- }
- }
package memory; import com.javamex.classmexer.MemoryUtil; class A { byte a; int b; boolean c; long d; Object e; } //-javaagent:classmexer.jar public class ClassMexerTest { public static void main(String[] args) { A a = new A(); long byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(a); System.out.println("MemoryUsage of A =" + byteArrayMemoryUsage); int[] i1 = new int[10]; byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i1); System.out.println("MemoryUsage of int[10] =" + byteArrayMemoryUsage); int[][] i2 = new int[10][10]; byteArrayMemoryUsage = MemoryUtil.deepMemoryUsageOf(i2); System.out.println("MemoryUsage of int[10][10] =" + byteArrayMemoryUsage); } }
4.3 编译时加入下载好的classmexer.jar即可,
运行时要加入JVM参数 -javaagent:./lib/classmexer.jar (我把jar放在工程根目录下的lib目录里了)
4.4 运行结果
MemoryUsage of A =32
MemoryUsage of int[10] =56
MemoryUsage of int[10][10] =616
验证了上面的理论。
4.5 常见错误
如果出现以下错误,多半是因为找不到那个jar包,请仔细核对jar包路径和指定的-javaagent参数有没有匹配。
- Error occurred during initialization of VM
- agent library failed to init: instrument
- Error opening zip file or JAR manifest missing : lib/classmexer.jar
Error occurred during initialization of VM agent library failed to init: instrument Error opening zip file or JAR manifest missing : lib/classmexer.jar
相关推荐
有效测量出 java 对象 内存 大小 可供缓存等计算
JAVA对象所占内存大小计算例子,博文地址:http://blog.csdn.net/u012787710/article/details/53164226
统计缓存大小(查看java对象所占的内存大小).
java 使用静态成员变量计算内存中实例化的对象数目
使用 Memory Analyzer 来分析生产环境的 Java 堆转储文件,可以从数以百万计的对象中快速计算出对 象的 Retained Size,查看是谁在阻止垃圾回收,并自动生成一个 Leak Suspect(内存泄露可疑点) 报表。 Memory ...
这个简单的项目提供了一种有效地计算任何Java对象的实际内存使用量的方法。 该类利用JVM自身的工具支持以可移植的方式计算对象内存的使用。
计算机后端-Java-PHP视频教程javascript01-13 获取对象在内存中计算后的样式.wmv
通过在规则引擎中引入内存表格的对象,我们可以把常用的数据字典类数据直接保存在内存中,这样在规则中 我们直接来访问内存中的数据,提高规则的执行效率,也可以把数据库中的数据读取出来,然后存储在内存表中,...
使用情况,得出对象内存泄漏的可能性大小,量化对象内存泄漏的风险。检测 系统首先收集垃圾回收事件后的应用内存数据,确定进行内存泄漏分析的时间 区间。然后通过收集每次垃圾回收事件后对象之间的引用关系...
命令行: java -XX:+PrintCommandLineFlags -version 查看jvm默认参数 分别是 -XX:+UseCompressedOops 和 -XX:+UseCompressedClassPointers 这2个参数都是默认开启(+代表开启,-代表关闭) UseCompressedOops:普通...
很多人错误的认为运行Java程序时使用-Xmx和-Xms参数指定的是程序将会占用的内存,但是这实际上只是Java堆对象将会占用的内存。堆只是影响Java程序占用内存数量的一个因素。要更好的理解你的Java程序将会占用多大的...
下载的资源文件中,封装了并发计算以及内存溢出解决方案的工具类GroovyEngine.java,调用示例: GroovyEngine engine = GroovyEngine.getInstance(); engine.put("a",1); engine.put("b",2); Object v1 = engine....
计算机后端-Java-Java核心基础-第15章 面向对象07 08. 类变量和实例变量的内存解析.avi
主要介绍了解析Java程序中对象内存的分配和控制的基本方法,包括计算对象的内存占用的方法,要的朋友可以参考下
Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念...
一种通用的内存池(也位于RAM区),用于存放所有的java对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当...
Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...
JVM堆:所有线程共享的运行时内存区域,是GC回收的主场所,Java堆保存Java的实例对象,从内存回收对象的存活来分析,堆又可以分为新生代、老年代。 方法区:方法区是线程共享的运行时内存区域,存储虚拟机加载的类的...
本文介绍了计算机的一些主要部件,包括中央处理器、内存、硬盘、输入设备和输出设备,并提供了相应的Java示例代码。 内容概要 本文档涵盖以下内容: 中央处理器(CPU)的功能和多线程编程示例 内存的层级和操作...