最近在做一个小项目,需要把所有数据刷到内存中,避免采用redis或者其他内存数据库需要多次IO,数据大约9万条,因此要估计下大概需要耗费多少内存,以评估可以在server上部署多少个应用,突然有点懵,期初都是通过Runtime.totalMemory-Runtime.freeMemory来计算,但是这样似乎并不是很好,下面我们来分析分析一个对象到底占用多少内存。
先看一个表:
类型 | 未压缩(字节) | 压缩(字节) |
boolean | 1 | 1 |
byte | 1 | 1 |
short | 2 | 2 |
char | 2 | 2 |
int | 4 | 4 |
float | 4 | 4 |
long | 8 | 8 |
double | 8 | 8 |
reference | 8 | 4 |
数组 | 24 | 16 |
以上数据受到jvm参数压缩未压缩(UseCompressedOops)设定影响,这是基础。
我们再来看看Java对象的内存布局:对象头(Header),实例数据(Instance Data)和对齐填充(Padding),对于padding,是因为占用字节数必须是8的倍数,你可以简单认为是凑数,因为因此内存占用也要从这几方面考虑。比如我们有一个类
class A{
int a;
}
头对象未压缩是16字节,压缩是12字节,因此:
未压缩:16(头对象)+4(a)+4(padding)=24字节
压缩:12(头对象)+4(a)=16字节
再看如下代码
class A{
int a;
Integer b;
}
因为 b是对象的引用,需要占用8个字节,因此
未压缩:16(头对象)+4(a)+8(b)+4(padding)=32字节
压缩:12(头对象)+4(a)+8(b)=24字节
我们再分析下数组,数组是个特殊的对象,64位机器上,数组对象的对象头占用24个字节,启用压缩之后占用16个字节。之所以比普通对象占用内存多是因为需要额外的空间存储数组的长度。
比如 Integer[0],长度为0,只有头对象,因此是24或者16
再比如Integer[3]
未压缩:24+8*3=28
压缩:16+4*3+4(padding)=32,你也应该知道Integer[4]在压缩下还是32
最后再看一段代码:
static class B {
int a;
int b;
}
static class C {
int ba;
B[] as = new B[3];
C() {
for (int i = 0; i < as.length; i++) {
as[i] = new B();
}
}
}
我们先来看下这个对象的内存结构吧:
未压缩:
3个B实例:(16(头对象)+4(a)+4(b))*3=72
数组对象:24(头对象)+8(B引用)*3=48
C实例:16(头对象)+4(ba)+8(as引用)+4(padding)=32
压缩:
3个B实例:(12(头对象)+4(a)+4(b)+4(padding))*3=72
数组对象:16(头对象)+4(B引用)*3+4(padding)=32
C实例:12(头对象)+4(ba)+4(as引用)+4(padding)=24
因此一个c实例占用空间为:
未压缩:72+48+32=152
压缩:72+32+24=128
这就是对象占用空间的分析过程。
当然了,现实中,我们不可能去一个一个对象分析内存占用情况,那么代码如何实现呢,我们可以参考这篇博客:
http://brandnewuser.iteye.com/blog/2113828
此片博客是借鉴别人博客以及我个人理解,欢迎大家拍砖。
借鉴博客位置:
http://www.cnblogs.com/magialmoon/p/3757767.html
- 大小: 31 KB
分享到:
相关推荐
本文将深入探讨如何计算Java对象所占内存,并通过提供的代码示例进行详细解析。 首先,我们需要理解Java对象内存占用的基本原理。每个Java对象都由三部分组成:对象头(Object Header)、实例数据(Instance Data)...
1. **Java VisualVM**:这是一个强大的Java性能分析工具,可以显示对象的大小、内存分配和垃圾回收情况。通过“对象”视图,可以观察到对象实例的大小。 2. **JOL (Java Object Layout)**:JOL是一个轻量级库,它...
此外,JOL库(Java Object Layout)是一个非常有用的工具,可以帮助我们分析JVM中对象的内存布局。通过引入该库,可以方便地获取对象和数组的详细内存占用信息。 总之,Java对象和数组的内存占用取决于JVM的配置、...
对于仅包含虚函数的类,编译器会在对象内存中添加一个虚函数指针(vptr),用于指向虚函数表。虚函数表则包含了类中的所有虚函数地址。即使类中没有其他成员变量,也会为vptr分配空间,因此这类对象的大小通常至少为...
delphi 中对象所占内存空间的分配
在Java编程语言中,了解一个对象占用的内存字节数对于优化内存使用和理解程序性能至关重要。本篇文章将深入探讨如何计算Java对象占用的内存字节数,以及影响这一数值的因素。 首先,Java对象在堆内存中由四个部分...
在Java编程语言中,计算一个对象的大小是一个相对复杂的过程,因为对象的内存布局涉及到多个因素,包括对象头、实例字段、对齐填充等。这个主题通常与性能优化和内存管理有关,尤其是在处理大规模数据结构时。这篇...
Delphi“对象所占内存空间大斜的演示程序,《Delphi高手突破-Design In Delphi》随书光盘的附带示例,在我本机运行得到的结果:对象大小:20 对象所在地址:9773280 FMember1所在地址:9773284 FMember2所在...
Java对象在JVM中的内存占用是一个复杂而重要的主题,它涉及到Java虚拟机的内存区域划分、对象头、实例数据以及对齐填充等多个方面。这里我们将深入探讨这些知识点,以便更好地理解和优化Java应用程序的性能。 首先...
"计算对象占用内存空间ObjectSize-master.zip" 提供的工具可能是一个帮助开发者分析和估算对象在内存中占用大小的解决方案。这样的工具对于调试、性能调优以及避免内存泄漏至关重要。 在Java中,对象的内存占用不...
在Java编程语言中,了解一个对象的大小是重要的性能优化技巧之一。这涉及到内存管理和垃圾回收的细节。本文将深入探讨如何计算Java对象的大小,以及这个知识点在实际开发中的应用。 首先,Java对象的大小不仅仅包括...
即使添加了一个int类型的成员变量,SizeObject的实例对象占用的内存大小仍然是16个字节。 然后,文章介绍了计算实例实际使用内存的空间的方法。使用malloc_size函数可以计算出系统实际分配的内存空间。结果表明,在...
在内存布局方面,每个Java对象都有一个对象头(object header),它由两部分组成:标记字段和类型指针。标记字段用于存储对象的运行时数据,如对象的哈希码、垃圾收集信息以及锁状态。类型指针则指向对象的类元数据...
在开发Spring Cloud应用程序时,经常会遇到一个问题,那就是内存占用过高,这对本地开发环境来说是一个显著的挑战。即使没有大量的请求,内存的高消耗也可能导致IDE(集成开发环境)变得卡顿甚至崩溃。例如,一个...
《C++ UMP:一个通用的线程安全内存池》 在C++编程中,内存管理是至关重要的一环。为了提高程序性能并优化资源利用,内存池技术应运而生。本文将深入探讨UMP(通用线程安全内存池)的概念、实现原理以及它在C++中的...
Android 提供了一个便捷的方法 `getByteCount()`,用于计算 Bitmap 在内存中的大小。该方法通过高度和每行字节数相乘得到总字节数。其中,`getRowBytes()` 返回 Bitmap 的每一行像素占用的字节数。例如,一张 522...
对于CPU和内存使用率图,我们通常会有一个时间轴(x轴)和两个数值轴(y轴,一个表示CPU利用率,另一个表示内存使用率)。设置坐标轴的范围和刻度,确保它们能适应实际数据的动态变化。 接下来,创建两个图形对象...
创建了一个包含1000个long类型元素的数组,由于long类型占8个字节,因此整个数组对象会占用8 * 1000 + 对象头大小的内存空间。再比如,一个包含1000个null引用的Object数组Object[] objs = new Object[1000];,每个...
`API_SetProcessWorkingSetSize`允许我们设定一个进程的工作集大小,工作集是进程在物理内存中保留的页面集合。通过适当设置这个值,可以强制操作系统释放不常使用的内存页面,从而达到减少内存占用的目的。需要注意...
8. **内存泄漏**:虽然Java有垃圾收集机制,但不恰当的编程习惯可能导致内存泄漏,比如全局变量引用了一个不再使用的大型对象,即使该对象不再被其他地方引用,也无法被垃圾收集。 9. **Java虚拟机参数调整**:...