确定Java内存使用情况。

5
嗯,有没有Java内存使用方面的入门指南?我原本以为Sun或IBM会有一篇好的文章,但我找不到任何看起来真正可靠的东西。我想知道两件事:
1.在运行时,如何确定我的包中的类在特定时间使用了多少内存 2.在设计时,估计各种事物的通用内存开销,例如: - 创建一个空对象需要多少内存开销(除其字段所需的空间外) - 创建闭包需要多少内存开销 - 创建ArrayList等集合需要多少内存开销
我可能会创建数十万个对象,我希望成为一个“好邻居”,不要过度浪费RAM。我的意思是,我并不关心我是否比“最佳情况”多使用10%的内存,但如果我正在实现某些东西,它使用的内存是我可以通过简单更改而减少5倍,则我希望使用更少的内存(或能够在固定的可用内存量下创建更多的对象)。
我发现了几篇文章(Java专家通讯和来自Javaworld的一些内容),以及一个内置类java.lang.instrument.getObjectSize(),声称可以测量"近似"(??)的内存使用情况,但这些都似乎有点模糊不清...(我意识到在两个不同操作系统上运行的JVM可能会为不同对象使用不同数量的内存)

我在这里基本上回答了同样的问题:https://dev59.com/g1HTa4cB1Zd3GeqPPz1B#3966510 - Dimitris Andreou
8个回答

4

我几年前使用过JProfiler,它表现不错,并且可以将内存使用情况细分到相当精细的级别。


4
自Java 5以来,在支持它的Hotspot和其他VM上,您可以使用Instrumentation接口询问VM给定对象的内存使用情况。虽然有点棘手,但您可以做到。 如果您想尝试此方法,我已经在我的网站上添加了一个页面使用Instrumentation框架查询Java对象的内存大小
作为在32位机器上Hotspot的粗略指南:
  • 对象使用8个字节进行“清理”
  • 字段使用其位长度所期望的内容(尽管布尔值 tend to be allocated an entire byte)
  • 对象引用使用4个字节
  • 整体对象大小具有8个字节的粒度(即,如果您有一个具有1个布尔字段的对象,则它将使用16个字节;如果您有一个具有8个布尔字段的对象,则它也将使用16个字节)
在虚拟机处理集合方面,它们没有什么特别之处。它们的内存使用量是其内部字段的总和加上(如果你计算的话)它们包含的每个对象的使用量。您需要考虑诸如ArrayList的默认数组大小以及该大小在列表满时增加1.5的事情。但是,无论是询问VM还是使用上述指标,查看集合的源代码并“通过”将基本上使您得到答案。
如果您所说的“闭包”类似于Runnable或Callable,那么它只是一个像其他任何对象一样的普通对象而已。(注意:它们实际上不是闭包!!)

清理旧的未被接受的问题:如果您能指向在32位机器上使用Hotspot对象的源,例如8字节的housekeeping + 4字节的objrefs + 8字节的粒度,我会接受这个答案。 - Jason S
这些实际上来自Hotspot源代码中的结构,尽管它们是通过实际测量得出的。显然,这些数字仅适用于32位版本。我承认我不知道Java 7是否有任何改动,但我认为应该没有。 - Neil Coffey

3

您可以使用 JMP,但它只支持Java 1.5。


1

我已经使用过 Netbeans 的新版本中附带的 profiler 几次了,它非常好用,可以为您提供有关程序内存使用和运行时间的大量信息。绝对是一个很好的起点。


1

如果您正在使用1.5版本之前的虚拟机 - 您可以通过使用序列化来获取对象的大致大小。但请注意..这可能需要为该对象分配两倍的内存。


0

看看 PerfAnal 是否能给你想要的结果。


看起来这是一个很好的用于分析 CPU 使用情况的工具,但它是否也可以分析内存使用情况呢?我浏览了一下文章,似乎没有提到。 - Jason S

0

0

我相信Netbeans中包含的分析器也可以监控内存使用情况,你可以试试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接