【问题标题】:How do I estimate a class's total permgen memory consumption?我如何估计一个类的总 permgen 内存消耗?
【发布时间】:2012-06-14 16:06:29
【问题描述】:

最近,我正在编写一个类,在该类中我发现我可以将实例的内存消耗减少约 10 字节/元素,但代价是使代码更加复杂。这将编译后的 .class 文件的大小增加了约 10KB。

我假设 JVM 必须将 .class 文件加载到内存中,因此除非至少有 1000 个左右的元素,否则这些更改不会收回成本。但是,除非类文件中额外的 10KB 是增加代码复杂性的唯一成本,否则该算法行不通。

This Oracle blog 表明 permgen 中的类消耗了相当多的额外内存,而不仅仅是基于.class 文件——例如,我怀疑更复杂的代码可能需要更多内存用于优化元数据。

所以,这个问题有两个部分:

  • 如何测量特定类的实际 permgen 内存消耗?是在运行时使用一些工具,还是使用分析工具?
  • 有没有一种方法可以在我编写该类时估计它的 permgen 内存消耗? (使用some background knowledge,您可以在编写类实例时估计它们的内存消耗;我想知道我们是否可以估计类本身的永久内存消耗。)

Dalvik VM 的类似细节将不胜感激,但我主要关注 OpenJDK 和其他“主流”JVM。

【问题讨论】:

  • 内存需求也取决于 HotSpot 是否编译它。 JITed 代码有其自身的成本。
  • @JesseWilson:这显然是正确的,但有没有一种好的方法来估算成本?只是原始组件的消耗,还是有很多额外的簿记?
  • 我可能会说一些奇怪的东西,但是既然 XXX.class 是 Class 的一个实例,我们就不能使用与普通实例相同的方法吗?像 Java 代理的 getObjectSize 方法一样?但也许它不包括你所说的“优化元数据”

标签: java jvm permgen


【解决方案1】:

如何测量特定类的实际 permgen 内存消耗?是在运行时使用一些工具,还是使用分析工具?

一种方法是在不同的类加载器中加载要测量的类,并使用jmap -permstat,如blog entry 中所述。

对于每个类加载器对象,打印以下详细信息:

  1. 类加载器对象的地址 - 实用程序运行时的快照。
  2. 已加载的类数(由此加载器使用方法 (java.lang.ClassLoader.defineClass) 定义。
  3. 此类加载器加载的所有类的元数据消耗的大致字节数。
  4. 父类加载器的地址(如果有的话)。
  5. “活”或“死”指示 - 指示加载器对象将来是否会被垃圾回收。
  6. 这个类加载器的类名。

【讨论】:

  • 哦哦哦。我会对此进行调查。
  • @LouisWasserman - 调查后你有没有想出更多信息?
【解决方案2】:

这是对第二点的回答;我不确定这会有多大用处,但我发现演示文稿 Building Memory-efficient Java Applications: Practices and Challenges 中的幻灯片对于估计各种 Java 对象的大小和运行状况非常有帮助。在估算 32 位和 64 位 JVM 中对象的大小时,他做了很多详细的说明,还提供了指针以使您的对象更节省内存。

【讨论】:

  • 确实,这个演示文稿促使我尝试编写更复杂但每个元素实现更高效的内存,但现在我想知道我是否真的可能让问题变得更糟。 ;)
  • @LouisWasserman 不一定更糟,但可能更复杂一些。 :)
  • 嗯...如果内存中的实例中的元素从不超过 1000 个,那么它看起来可能更糟。
  • @LouisWasserman 我以为你在谈论你的代码!但是,是的,我同意。
猜你喜欢
  • 2011-12-23
  • 2015-03-17
  • 1970-01-01
  • 2022-06-14
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多