【超详细】Java各种类型所占用的内存空间究竟多大?
文章目录
- 准备工作
- 对象内存占用情况
- 使用Jprofiler进行验证
- 【关于Retained Size的意思】
- 基本类型的包装类型内存占用
- 数组占用内存空间
- String 对象内存占用空间
- 总结
准备工作
不喜欢被蒙在鼓里的感觉,鉴于网上大神们说法不一致,我决定亲自实验,探究究竟Java各个类型占用空间情况。
- 实验环境为 jdk1.8 hotspot虚拟机+win10系统
- 使用Jprofiler进行探究(IDEA插件直接下载)
- 另外还需要下载jprofile.exe,下载地址,破解方法百度既能找到!
- 关于jprofiler的具体使用先参考:这篇文章,具体之后再总结。
- 关于对象的内存布局,以及JVM的压缩指针,之前记录过了,具体看【这篇文章】即可!
对象内存占用情况
已知:Java对象的内存布局包括:1.对象头;2.实例数据;3.补充数据;
在jdk6之后的版本中,指针压缩是被默认开启的,开启指针压缩,对象头占用12bytes(其中markword 8字节,Klasspointer 4字节),不开启指针压缩则对象头占用16bytes(其中markword 8字节,Klasspointer 8字节)。【如果为数组还会存储数组长度,上面链接指向的文章中都有记录】
至于实例数据,原生类型(primitive type)的内存占用如下:
下面图片是我在别处截的,这个图存在一些问题。。这也是为什么自己想亲自写博客输出的原因之一,不喜欢被蒙在鼓里不清不楚的感觉。。
boolean在作为数组的时候会被编译器翻译成bytes[ ],所以只占一个字节,但是在单独作为实例变量的时候,boolean会被编译器翻译成int,占4个字节,所以具体多大还得具体分析!
至于实例数据中的,对象引用:开启指针压缩的内存优化,对象引用占用4字节,不开启的话占用8字节。
补充数据,是将当前的对象大小向上按照8字节的倍数进行补充,其原因上文连接中也介绍了。
使用Jprofiler进行验证
【注意使用Jprofile查看内存,不能让主线程立马结束,不然查看不了内存占用状况,需要写个sleep】
- 写个例子测试一下,下面是一个Wang的类,其中是一些实例变量
class Wang {private String name;private int age;private int[] arr = {1, 2, 3};private boolean status;
}
我们写个main方法进行测试一下这个对象占用了多少个字节
public static void main(String[] args) throws InterruptedException {Wang wang = new Wang("wangz7",18,true);Thread.sleep(600 * 1000);System.out.println(wang);
}
如图:我们发现这个对象占用了32个字节
(推测:对象头12字节 + String4字节 + int4字节 + arr数组引用4字节 + boolean4字节 + 6字节的补充数据)
【关于Retained Size的意思】
指的是:该对象指向别的对象,导致别的对象称为可达对象,那么Retained大小就包括自身的对象大小 + 指向的对象大小。
在这里wang对象持有了两个引用(String和int[ ]),说明这个String对象加上数组共占用64-32=32字节大小
引用关系如图所示
基本类型的包装类型内存占用
是否开启指针压缩 | 开启 | 关闭 |
---|---|---|
Byte, Boolean | 16 bytes | 24 bytes |
Short, Character | 16 bytes | 24 bytes |
Integer, Float | 16 bytes | 24 bytes |
Long, Double | 24 bytes | 24 bytes |
可以这么理解。只要是关闭指针压缩,那么一个包装对象在堆中就占用24字节空间
如果开启了指针压缩,那么除了双精度double以及Long这两个基本类型占8字节的包装类型,堆中占用还是24字节,其他的基本类型对应的包装类型均占16字节。
数组占用内存空间
探究这个问题我们可以用到这个工具:openjdk.jol
先添加依赖:
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.14</version>
</dependency>
然后可以参考我这个例子【这里写了个对象数组,并打印其对象内存占用情况】
class Wang {private String name;private int age;private int[] arr = {1, 2, 3};private boolean status;public Wang(String name, int age, boolean status) {this.name = name;this.age = age;this.status = status;}
}public class Solution {public static void main(String[] args) throws InterruptedException {System.out.println(VM.current().details());Wang[] wang = new Wang[10];System.out.println(ClassLayout.parseInstance(new Wang[10]).toPrintable());}
}
输出:
- 在64位机器上,开启压缩指针的情况下,对象头中会使用4个字节来描述数组长度,如上图(如果未开启,那么会通过8个字节进行存储数组长度)
- 因此对象头开启指针压缩占16个字节,不开启指针压缩占16+8=24字节。
- 注意一下,数组占用内存空间就不算对象中的一个个实例对象了,而是只保存引用,所以实例数据部大小 = 数组长度 * 引用4字节
- 从上图倒数第二行可以知道,这个wang数组对象共占用56字节,推导一下(对象头占用16字节 + 数组长度10 * 引用4字节 = 56 字节!)
- 下图为使用Jprofiler查看wang数组的大小,可以看到是56字节
- 为了严谨点实验,我们将数组增大到11的长度再试试其大小是否大了?
- 用jol打印发现确实跟上面描述的一样,刚好64字节
- Integer[10]数组同样是56字节(对象头16 + 数组长度 * Integer引用类型4字节 = 56字节)
- int[10]同样也是56字节(但是虽然占用内存相等,但是原因不同。这里注意是int类型,是长度 * int4字节,而不是上面的Integer引用类型占4字节)
String 对象内存占用空间
- 首先注意!String对象计算内存的时候有一些不同!因为String底层其实是使用数组实现的,但String又不完全由数组构成,还有成员变量hash值…因此计算String对象占用内存的时候需要既考虑到String对象本身,又要考虑到char[ ]的占用大小,并相加!
- 考虑到JDK1.9对String底层数据结构进行了优化(将char[ ]数组优化成了Byte[ ]数组),我们先分析JDK1.7到JDK1.8 String底层是char[ ]数组的情况!
- 补充一个知识点:就是static变量和方法是不与对象进行绑定的,因此使用他们的时候可以不用将对象new出来,直接通过他们的Class模板调用即可,因此他们的引用不是存在对象的实例数据中!而是和类的信息绑定在一起(注意如果是引用对象的话,引用和Class模板绑定,对象依旧在堆中。静态变量在JDK1.7后也均移到了堆中存储,而并非方法区)
- 我们来看看String类的源码:
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {private final char value[];private int hash; private static final long serialVersionUID = -6849794470754667710L;private static final ObjectStreamField[] serialPersistentFields =new ObjectStreamField[0];....省略...
可以看到除了一个char数组和一个int值,其他的是static修饰的不占用对象的内存。
因此一个String对象在开启指针压缩的64位机上,内存大小是(12字节对象头 + char数组引用4字节 + int4字节 + 4字节填充数据 = 24字节)
- 如果关闭了指针压缩的优化方案那么(16字节对象头 + 8字节数组引用 + 4字节int + 4字节补充数据 = 32字节)
之后再来计算char[ ]数组大小;毕竟String对象有数组的成分,在JDK1.7到JDK1.9之前是char[ ]。因此大小为(16字节对象头 + 字符串长度 * char占用2字节 + 补充数据),因此上面字符串“wang”的char[]数组部分占用16+4*2 = 24字节的大小
因此!在64位机下默认开启指针压缩,String str = new String(“wang”);这个str字符串对象的大小应该是String部分的24字节 + char数组部分的24字节 = 48字节
总结
- 稍稍了解这里就够了
- 本篇文章主要记录了一下各种类型占用的内存大小,以及使用jol和jprofiler证明对象的大小。
- 关于指针压缩、Retained Size、jprofiler的使用,我会记录下在并把连接放到下面:
————— END —————
【超详细】Java各种类型所占用的内存空间究竟多大?相关推荐
- 超详细Java安装教程
超详细Java安装教程 一.Java JDK下载 二.环境变量配置 一.Java JDK下载 下载方式: 官网下载 下载地址: https://www.oracle.com/java/technolo ...
- 解析一个Java对象占用多少内存空间
说明: alignment, 对齐, 比如8字节的数据类型long, 在内存中的起始地址必须是8的整数倍. padding, 补齐; 在对象所占据空间的末尾,如果有空白, 需要使用padding来补齐 ...
- 内存对齐 | 原来字段顺序还能影响结构体占用的内存空间
大家好啊,不知道看了网管在上周的文章Go指针的使用限制和unsafe.Pointer突破之路,你们有没有感觉Golang 比之前想的还好用呢?确实能直接读写内存,很多以前觉得无能为力的事情就不再是问题 ...
- PHP数组到底占用多少内存空间
http://www.ituring.com.cn/article/498349 本文翻译自 nikic 的一篇博文. PHP中的数组到底占用多大的空间? 简要:这篇文章我并不是按照原文逐字逐句的都翻 ...
- 有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度。 给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转
有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度. 给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转 ...
- 超详细——Java面试高频
目录 1.基础题 1.1面向对象和面向过程的区别 1.2 Java 语言有哪些特点 1.3 Java 和 C++的区别 1.6 字符型常量和字符串常量的区别 1.7 基本类型 1.8 构造器 Cons ...
- 超详细Java学习知识点-不定更新
练气期 一.了解 jvm就是Java虚拟机 通过这个进行编译 可以实现跨平台 jre包括jvm和运行java的核心库 jdk包含jre和开发工具:javac.exe 和 java.exe 二.开始he ...
- 微信支付-超详细java开发-小程序对接
文章目录 前言 微信支付接入前准备 1.思路介绍 2.如何注册小程序账号? 3.如何接入微信支付,需要准备哪些东西? 4.小程序接入前的准备(APPID及mchid以上两步已拿到,只需配置一下API ...
- 一看你就懂,超详细java中的ClassLoader详解
本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见.理解ClassL ...
最新文章
- Java垃圾回收之老年代垃圾收集器
- 弹性网络_理论物理所建立解析模型研究凝胶网络弹性介导的液液相分离现象
- gevent.hub.LoopExit: ('This operation would block forever'
- 阿里巴巴拿下奥运顶级赞助商
- ftp服务器网页空白,ftp服务器网页空白
- html语言 怎么清除用户名 name= password=,在html页面中填写注册表单后,它会给出这个错误,并使用用户名和密码并将值存储在登录表单中...
- c++返回指针时候注意提防_提防Java中的函数式编程!
- cs架构用什么语言开发_我为什么建议Python开发者将ES6作为第二语言
- 如何使用加密芯片完成SHA1摘要运算
- DiskFileItemFactory类的使用
- JavaScript Module Pattern
- python文件操作:文件指针移动、修改
- ivar和property
- Oracle分页查询
- 二级计算机c语言各题型,计算机二级C语言都有哪些题型?
- java毕业设计汽车零件厂绩效管理mybatis+源码+调试部署+系统+数据库+lw
- 我的世界java作弊怎么开_我的世界怎么开作弊?如何启用作弊模式?
- DirectX11 屏幕截图
- 黑马程序员--技术网站网址2
- 家具销售管理系统/家具在线商城