- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我试图了解 Java 中对象的内存占用量是多少。我读了this和其他关于 Java 中的对象和内存的文档。
但是,当我使用 sizeof Java library或 visualvm,我得到两个不同的结果,其中没有一个符合我根据之前的引用 (http://www.javamex.com) 所期望的结果。
对于我的测试,我使用的是 Java SE 7 Developer Preview
在 64-bits Mac
与 java.sizeof 0.2.1
和 visualvm 1.3.5
.
我有三个类,TestObject
, TestObject2
, TestObject3
.
public class TestObject
{
}
public class TestObject2 extends TestObject
{
int a = 3;
}
public class TestObject3 extends TestObject2
{
int b = 4;
int c = 5;
}
我的主要类(class):
public class memoryTester
{
public static void main(String[] args) throws Throwable
{
TestObject object1 = new TestObject();
TestObject2 object2 = new TestObject2();
TestObject3 object3 = new TestObject3();
int sum = object2.a + object3.b + object3.c;
System.out.println(sum);
SizeOf.turnOnDebug();
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object1)));
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object2)));
System.out.println(SizeOf.humanReadable(SizeOf.deepSizeOf(object3)));
}
}
使用 java.SizeOf() 我得到:
{ test.TestObject
} size = 16.0b
16.0b
{ test.TestObject2
a = 3
} size = 16.0b
16.0b
{ test.TestObject3
b = 4
c = 5
} size = 24.0b
24.0b
使用 visualvm 我有:
this (Java frame) TestObject #1 16
this (Java frame) TestObject2 #1 20
this (Java frame) TestObject3 #1 28
根据我在 Internet 上阅读的文档,因为我是 64 位的,所以我应该有一个 16 字节的对象头,对于 TestObject
来说没问题.
那么 TestObject2
我应该为整数字段添加 4 个字节,给出 20 个字节,我应该再次添加 4 个字节的填充,给 TestObject2
的总大小为 24 个字节.我错了吗?
对 TestObject3
继续这样做,我必须为两个应该提供 32 个字节的整数字段再添加 8 个字节。
VisualVm 似乎忽略了填充,而 java.sizeOf 似乎错过了 4 个字节,就好像包含在对象头中一样。我可以用 4 个 boolean 值替换一个整数,结果相同。
问题:
为什么这两个工具给出不同的结果?
我们应该有填充吗?
我还在某处读到(我没有找到链接),在一个类和它的子类之间可能有一些填充,对吗?在这种情况下,继承的类树可能会有一些内存开销?
最后,是否有一些 Java 规范/文档详细说明了 Java 正在做什么?
感谢您的帮助。
更新:
为了回答 utapyngo 的评论,为了获得 visualvm 中对象的大小,我创建了一个 heapdump,然后在“类”部分中,我检查了“实例”列之后的“大小”列。每种对象的实例数(如果为 1)。
为了回答 Nathaniel Ford 的评论,我初始化了每个字段,然后在我的 main 方法中对它们进行了简单的求和以利用它们。结果并没有改变。
最佳答案
是的,可能会发生填充。堆栈上的对象也可以完全优化。只有 JVM 知道任何时间点的确切大小。由于这种从 Java 语言中近似大小的技术都倾向于不同意,但是附加到 JVM 的工具往往是最准确的。我知道在 Java 中实现 sizeOf 的三种主要技术是:
这些技术都不准确。
如果您在 Oracle JVM 上运行,则在 v1.5 或之后。然后有一种方法可以直接从 Java 运行时使用的 C 结构中读取对象的大小。对于生产来说不是一个好主意,如果弄错了,你可能会导致 JVM 崩溃。但是,如果您想尝试一下,这里有一篇博文可能会让您觉得有趣:http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/
关于 Java 实际操作的文档,即 JVM 特定、版本特定和可能的配置特定。每个实现都可以自由地以不同的方式处理对象。即使在完全优化对象的范围内,例如,没有从堆栈中传递出来的对象也是空闲的,不会被分配到堆上。一些 JVM 甚至可以设法将对象完全保留在 CPU 寄存器中。这里不是你的情况,但我将它作为一个例子说明为什么获取 Java 对象的真实大小很棘手。
因此,最好将任何 sizeOf 值拿来用少许盐获得,并将其仅视为“指导”测量值。
关于Java 对象内存占用 - Visualvm 和 java.sizeOf 测量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15490561/
这个问题已经有答案了: Why isn't sizeof for a struct equal to the sum of sizeof of each member? (13 个回答) 已关闭 8
先生。 Stroustrup 在他的新书(TCPL 第 4 版)第 149 页写下了以下内容 1 N && sizeof(long)<=N任何 N 值的实现,更不用说任何人都会考虑使用 wchar_t
如 [5.3.3/3] 所述(expr.sizeof,工作草案): The sizeof operator can be applied to a pointer to a function, but
从C标准来看,int至少有16bit,long至少有32bit,long long如果有的话至少有64bit(有些平台可能不支持)。只是想知道标题中的句子是否总是正确的。 最佳答案 没有。该标准仅定义
我运行的是 Windows 7(64 位)。 这个问题与此处找到的问题相同: long on a 64 bit machine 但更深入,因为它处理更多的数据类型并适用到 C 或 C++,而不是 C#
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 8年前关闭。 Improve this
这个问题在这里已经有了答案: Length of array in function argument (9 个回答) 关闭 9 年前。 #include void printS(char []);
我承认这三个都有不同的含义。但是,我不明白这些具体情况适用于哪些特定情况。任何人都可以分享每个例子吗?谢谢。 malloc(sizeof(int)) malloc(size
To avoid things quietly breaking if you change the array size, I suggest std::copy(a, a + sizeof(a)/
我在 python 中注意到以下事实: >>> (1, 2, 3).__sizeof__() 48 >>> [1, 2, 3].__sizeof__() 64 我理解列表和元组之间的区别,但我希望它们
是否存在与指针大小相同的整数类型?保证所有微架构? 最佳答案 根据 this Wikipedia page ,在 C99 中,您的 stdint.h header 可能声明了 intptr_t 和 u
我注意到 int 和 double 的大小与使用函数 MPI_Type_size(MPI_INT, &MPI_INT_SIZE); 计算的不同。这是否意味着 sizeof(MPI_INT) 返回了错误
这个问题已经有答案了: How to find the size of an array (from a pointer pointing to the first element array)? (
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
为什么 sizeof 运算符返回的结构大小大于该结构成员的总大小? 最佳答案 这是因为添加了填充以满足对齐约束。 Data structure alignment影响程序的性能和正确性: 未对齐的访问
我是一名优秀的程序员,十分优秀!