如何计算一个对象占用的内存空间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何计算一个对象占用的内存空间相关的知识,希望对你有一定的参考价值。

java里面没有sizeof操作符,那么怎么才能知道我建的对象占用了多少内存阿?有没有直接的函数,或者说说原理我自己具体实现。

Java没有提供现成的函数去计算对象的内存空间,不过可以用大量产生某个对象然后计算平均值的方法近似获得该对象占用的内存。
写个例子给你:
public class Test
long f1 = Runtime.getRuntime().freeMemory();
for(int i=0;i<1000;i++)

MyObject t = new MyObject();

long f2 = Runtime.getRuntime().freeMemory();
System.out.println((f1-f2)/1000);//输出每个对象占用的字节数

参考技术A 着种功能有意义吗 假如有意义的话那JVM会考虑提供这个接口
反之 由于JVM没有提供 所以无意义!
再有 有很多类有很多 私有的成员 还有继承的成员 你看不到 如何通过你人工计算内存啊?可见这个问题只有JVM内部提供一个内存监视统计程序并给你用了。
参考技术B string.getBytes().length
只能得到串的字节数
参考技术C 对象的序列化行么? 你自己看看,不对的话别说我,哈哈哈哈哈哈啊啊啊啊哈哈哈哈哈哈后!~!~!~

Object流,直接将Object写入或读出,把一个Object直接转换成字节流写到硬盘上,
这里有一个类T:
class T implements Serializable // 必须要实现Serializable接口,才是可序列化的
int i = 10;
int j = 9;
double d = 2.3;
int k = 15;

这个类里面的成员变量3个int,1个double,int是4字节,double是8字节
所以对象的大小绝对不会小于20字节,但是T肯定是从Object类继承,那么继承下来这些内容也
占空间,比如方法什么的,所以肯定要大于20字节了

运行下面这个类:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Test
public static void main(String[] args)
T t = new T();
try
FileOutputStream fos = new FileOutputStream("d:/abc.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(t);
oos.flush();
oos.close();
catch (IOException e)
e.printStackTrace();




直接将T对象通过Object流写到了D盘的名为abc.txt的文件里面
一个空文本文件是0字节,找到这个文件以后查看它的属性,我这里是67 字节,
那么这个对象就是67 字节

现在在T类中添加一些其他内容,那么再次输出,字节数肯定就比原来大了,它就是把整个对象转换成
字节,写入了文件,这个应该算是比较好的方式了,但是我无法特别精确的知道对象中哪些内容各自
占用多少空间,学的没那么深入,水平有限

当然,把一个对象写进去,也可以读出来:
FileInputStream fis = new FileInputStream("d:/abc.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
// 当成Object读出来的,强转成T类型
T tReaded = (T)ois.readObject();
System.out.println(tReaded.i + " " + tReaded.j + " " + tReaded.d + " " + tReaded.k);
发现打印出的成员变量的值,还是存进去这个对象的值 .

c++ 之 内存模型:对象篇

一、对象

 1.类对象所占用的空间

    (1)类的普通成员函数不占用类对象的成员空间

    (2)一个类对象至少要占用1字节的内存空间

    (3)类的普通成员变量占用类对象的空间(每一个类的对象拥有属于自己的成员变量)

    (4)类的普通成员函数虽然写在类的定义中,但普通成员函数不会占用类对象的内存空间

    (5)所有类的对象公用一份成员函数

 2.C++对象结构发展和演化

    (1)非静态的成员变量跟着对象走(存在于对象内部)(每一个类的对象拥有属于自己的成员变量)

    (2)静态成员变量所占用的内存空间于类对象无关,所有类对象公用一份静态成员变量。是归属于类本身的。

    (3)成员函数:不管静态还是非静态。全部保存在类对象之外。不占用具体的类对象的内存。

    (4)虚函数:类不管存在几个虚函数(>=1),会占用类对象内存的4个字节(和具体的机器相关)。(存储虚函数表地址)

         类中包含一个及以上的虚函数时,类会产生数量对应的指向虚函数的指针。这些指针存储一个表格里——虚函数表(virtual table [vtbl]),一般保存在可执行文件中,在程序执行时载入到内存里。

         虚函数表是基于类的。

         如果一个类包含虚函数,系统在类的对象中会添加一个指针指向该类的虚函数表,该指针被称为[vptr]。[vptr]的值是系统在适当的时机(比如构造函数中增加额外的代码实现)添加。

    (5)内存对齐:如果一个类有多个数据成员,那么为了提高访问速度,某些编译器可能会将数据成员之间的内存占用比例进行适当的调整。 

    (6)指针占用的内存大小:不管是什么类型的指针,指针在同一平台上的占用内存大小是一样的

指针大小是指针变量占用内存的大小(字节数).
在32位机上,所有指针类型变量占用内存字节数都为4
因为32位机就是 4字节 * 8个二进制位/字节 计算出来的.
如果在64位机上,指针占用内存大小就是:8个字节.

X86:32位(一般i386是32位CPU的统称)

X64:64位(代表CPU:IA64,现在几乎没有这样纯粹的64位CPU,都是兼容32位的64位CPU,如下)

X86_64:兼容32位的64位CPU,是64位(Intel的叫法)

AMD64:兼容32位的64位CPU,是64位(AMD的叫法)

 电脑处理器的位数,是表达了处理器的地址编码有多少个位。仅仅表达了寻址能力。
32位电脑,它告诉我们,地址有32个位,如果你想保存这个地址,需要使用32个位的空间来保存,就是4个字节。
double *x =a; //x这个变量的值,是一个地址。不管它指向什么类型的变量,地址只是一个变量存放的地址(指针)而已,地址是CPU统一编址的。CPU位数告诉你这个地址有多长。
cout<<sizeof(x)<<endl;输出CPU地址的编码长度,你是32位CPU,输出地址就是32位的,需要4个字节。因此sizeof输出4.

 

 

 

 

以上是关于如何计算一个对象占用的内存空间的主要内容,如果未能解决你的问题,请参考以下文章

如何获得一个存活的java对象的内存占用大小?

一条TCP连接时占用内存空间多少?

JVM —— Java 对象占用空间大小计算

PHP数组到底占用多少内存空间

C程中如何计算数组(一维及二维)占内存空间的大小

如何计算Java对象所占内存的大小