预测Java内存

时间:2012-08-17 16:46:43

标签: java java-ee memory memory-management

有没有办法预测我的Java程序会占用多少内存?我来自C ++背景,我在类上实现了诸如“size_in_bytes()”之类的方法,我可以相当准确地预测我的应用程序的运行时内存占用量。现在我在Java世界中,这并不是那么容易......有共享的引用,池,不可变对象......但我仍然希望能够在我查看之前预测我的内存占用流程大小在顶部。

4 个答案:

答案 0 :(得分:2)

如果使用instrumentation API,则可以检查对象的大小。使用起来有点棘手 - 它需要一个“premain”方法和额外的VM参数 - 但网上有很多例子。 “ java检测规模”应该可以找到这些。

请注意,默认方法只会为您提供大小。除非你在构造函数之外避免任何对象构造(这几乎是不可能的),否则会有等待垃圾收集的死对象。

但一般情况下,如果您能够很好地控制生成的对象数量,就可以使用它们来估算应用程序的内存需求。

答案 1 :(得分:1)

您无法预测程序将要占用的内存量。但是,您可以预测对象将采取多少。 编辑结果证明我几乎完全错了,本文档更好地描述了对象的内存使用情况:http://www.javamex.com/tutorials/memory/object_memory_usage.shtml

答案 2 :(得分:1)

通常,您可以非常仔细地预测给定对象需要什么。有一些相对固定的开销,加上对象中的实例字段,加上适量的填充。但是,对象大小至少(在大多数JVM上)四舍五入到16字节边界,并且一些JVM将一些对象大小向上舍入到更大的边界(以允许使用标准大小的预分配对象帧)。但对于给定的JVM,所有这些都是相对固定的。

当然,不同的是垃圾收集所需的开销。一个天真的垃圾收集器需要100%的开销(每个分配的字节至少有一个空闲字节),尽管某些类型的“世代”收集器可以在一定程度上改善这一点。但是GC需要多少空间高度依赖于工作负载(在大多数JVM上)。

另一个问题是,当你以相对较低的分配水平运行时(你只使用10%的最大可用堆),垃圾就会累积。它没有被主动引用,但垃圾的位数散布在您的活动对象中,因此它占用了工作集。因此,您的工作集往往大致等于当前整体垃圾收集堆大小(加上其他系统开销)。

当然,您可以“限制”堆大小,以便以更高的利用率运行,但这会增加垃圾收集的频率(以及GC的总体成本到较低程度)。

答案 3 :(得分:0)

您可以使用分析器来了解始终在内存中的常量对象集。然后,您应该执行所有代码路径以检查内存泄漏。 JProfiler是一个很好的开始。