java各种类型对象占用内存情况分析
作者:狮少 发布时间:2023-08-22 10:32:05
前言
其实一般的程序猿根本不用了解这么深,只有当你到了一定层次,需要了解jvm内部运行机制,或者高并发多线程下,你写的代码对内存有影响,你想做性能优化。等等等等,一句话,当你想深入了解java对象在内存中,如何存储,或者每个对象占用多大空间时,你会感谢这篇文章
本文主要分析jvm中的情况,实验环境为64位window10系统、JDK1.8,使用JProfiler进行结论验证
很多描述以及 概念是基于你懂基本java知识的,如果你看起来有点吃力,要加油咯
本片更偏重验证,更多理论,请参考:https://segmentfault.com/a/1190000006933272
内存公式:Java对象的内存布 = 对象头(Header) + 实例数据(Instance Data) + 补齐填充(Padding)。
补齐填充:Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数
Shallow Size
对象自身占用的内存大小,不包括它引用的对象。
针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。
针对数组类型的对象,它的大小是数组元素对象的大小总和。
Retained Size
Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用)
换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。
不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage。
基本数据类型占用
类型 | 占用空间 |
---|---|
boolean、byte | 1byte |
short、char | 2byte |
int、float | 4byte |
long、double | 8byte |
接下来用JProfiler验证:
1.新建一个空对象,观察空对象内存占用
public class TestObject {}
对象占用内存 16b,如图
结论:一般自建空对象占用内存 16b,16 = 12(Header) + 4(Padding)
2.在TestObj中新增一个 int 属性,观察对象内存占用
public class TestObj { private int i;}
对象占用内存 16b,如图
结论:int 占用 4b, 16 = 12(Header) + 4(int)
3.在TestObj中新增一个 long 属性,观察对象内存占用
public class TestObj { private long i;}
对象占用内存 24b,如图
结论:long 占用 8b, 24 = 12(Header) + 8(long) + 4(Padding)
其余基本类型可以参照以上自行验证,原理一样
包装类型占用
包装类(Boolean/Byte/Short/Character/Integer/Long/Double/Float)占用内存的大小 = 对象头大小 + 底层基础数据类型的大小。
包装类和其他引用类一样,会产生一个引用(reference)
类型 | 占用空间 |
---|---|
Boolean、Byte | 16byte |
Short、Char | 16byte |
Integer、Float | 16byte |
Long、Double | 24byte |
1.在TestObj中新增一个 Integer 属性,观察对象内存占用
public class TestObj {
private Integer i =128;
}
对象占用内存 32b,如图
结论:Integer 占用 16b, 32 = 12 (Header) + 16(Integer) + 4(reference)
特别的:-128~127 在常量池,只占用 4b,且不产生引用(reference)
2.在TestObj中新增一个 Long 属性,观察对象内存占用
public class TestObj {
private Long l = new Long(1);
}
对象占用内存 40b,如图
结论:Long 占用 24b, 40 = 12 (Header) + 24(Long) + 4(reference)
其余包装类型可以参照以上自行验证,原理一样
基本类型数组占用
64位机器上,数组对象的对象头占用24 bytes,启用压缩后占用16字节。比普通对象占用内存多是因为需要额外的空间存储数组的长度(普通16b-12b)。
对象数组本身的大小=数组对象头 + length * 存放单个元素大小
在TestObj中新增一个 char[] 属性,观察对象内存占用
public class TestObj {
private char[] c = {'a','b','c'};
}
char[] c占用内存 40b,如图
结论:char[3] 占用 24b, 24 = 40 - 16,24 = 16(Header) + 3 * 2(char) + 2(Padding)
封装类型数组占用
封装类型数组比基本类型的数组,需要多管理元素的引用
对象数组本身的大小=数组对象头+length * 引用指针大小 + length * 存放单个元素大小
在TestObj中新增一个 Integer[] 属性,观察对象内存占用
public class TestObj {
private Integer[] i = {128,129,130};
}
Integer[] i占用内存 80b,如图
结论:Integer[3] 占用 80b, 80 = 96 - 16, 80 = 16(Header) + 3 * 4 (reference)+ 3 * 16(Integer) +4(padding)
String占用内存
在TestObj中新增一个空 String 属性,观察对象内存占用
public class TestObj {
private String s = new String("");
}
对象占用内存 40b,如图
结论:String 本身占用 24b, 24 = 40 -16,也就是说空""也需要16b
注意:这里为什么要写String s = new String("")?请自己思考,不写会怎么样?
答:如果写成String s = “”,是不会再堆中开辟内存的,也就看不到String占用的空间,你看到的将会是下面的,至于为什么,都是因为final
来源:https://blog.csdn.net/qq_30054961/article/details/88345030


猜你喜欢
- 前言大家好,我是bigsai,在数据结构与算法中,二叉树无论是考研、笔试都是非常高频的考点内容,在二叉树中,二叉树的遍历又是非常重要的知识点
- 前言Android底层服务,即运行在 linux 下的进程,是 Android 系统运行的基础,完成 Android 或者说计算机最基本的功
- 1.1、获取http请求参数是一种刚需我想有的小伙伴肯定有过获取http请求的需要,比如想前置获取参数,统计请求数据做服务的接口签名校验敏感
- 前言废话不多说直接开始老规矩,文章最后有源码完成效果图棋子加渐变色棋子不加渐变色一、测量1.获取宽高 @Override protected
- 在使用Java web开发的后端工程师们大多会使用Maven作为项目构建以及编译的工具,微服务和大中台当道的今天,更加关注maven的细节是
- 1.元组(Tuple)元组(Tuple)在4.0 的时候就有了,但元组也有些缺点,如: 1)Tuple 会影响代码的
- 1.控制屏幕常亮首先导入模块import brightness from '@system.brightness';接下来在
- 在 C# 中,程序中在运行时出现的错误,会不断在程序中进行传播,这种机制称为“异常”。异常通常由错误的代码引发,并由能够更正错误的代码进行
- 这篇文章主要介绍了SpringBoot+SpringCloud实现登录用户信息在微服务之间的传递,文中通过示例代码介绍的非常详细,对大家的学
- 本文实例为大家分享了Java实现酒店客房管理系统的具体代码,供大家参考,具体内容如下LoginFrame.javapackage login
- 使用 try/catch 处理异常try-catch 块的用途是捕捉和处理工作代码所生成的异常。 有些异常可以在 catch 块中处理,解决
- 前言 短时间提升自己最快的手段就是背面试题,最近总结了Java常用的面试题,分享给大家,希望大家都能圆梦大厂,加油,我命由我不由天
- 今天在安装VS2019的时候,在安装的过程中一直无法进入安装界面,在网上找了各种方法试了将近40分钟都没有找到有效的办法,不过就快放弃的时候
- 本文实例讲述了JAVA基于数组实现的商品信息查询功能。分享给大家供大家参考,具体如下:综合一维数组和二维数组的相关知识,以及数组排序的多种算
- 先对问题进行描述:(1)在MyEclipse Servers视图在MyEclipse 10.7.0在某些情况下,可能无法打开。 试图打开视图
- 本人从开始用Android Studio到现在已经快一年了吧,在我刚开始用的时候Android Studio还是1.2的版本。当时安装会因为
- 一、什么是备忘录模式定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态
- 背景现行的文本编辑器大多都具备文本查询的能力,但是并不能直观的告诉用户两段文字的细微差异,所以对比工具在某种情况下,就起到了很便捷的效率。关
- 想问下这是什么情况。在导入一个maven项目时只有一个finish,点击完finish后没有任何反应。。。各位大佬给看下这是什么问题。急,在
- ExecutorsExecutors 是一个Java中的工具类. 提供工厂方法来创建不同类型的线程池.从上图中也可以看出, Executor