【问题标题】:Does allocation speed depend on the garbage collector being used?分配速度是否取决于所使用的垃圾收集器?
【发布时间】:2010-06-01 16:30:57
【问题描述】:

我的应用正在分配大量对象(每秒超过 100 万;大多数对象是大小约为 80-100 的字节数组和大小相同的字符串),我认为这可能是其性能不佳的原因。

应用程序的工作集只有几十兆字节。分析应用程序显示 GC 时间小到可以忽略不计。

但是,我怀疑分配过程可能取决于正在使用的 GC,并且某些设置可能会使分配更快,或者可能对缓存命中率产生积极影响等。

是这样吗?或者在垃圾收集本身花费很少时间的假设下,分配性能是否独立于 GC 设置?

【问题讨论】:

  • 您分配的对象是长期存在的,还是它们一创建就超出范围?
  • 它们的寿命很短:每 10-20 次左右分配就会超出范围。

标签: java performance garbage-collection memory-management


【解决方案1】:

当然,您的性能取决于使用的分配器。但是您已经分析了 GC,发现这不是什么大问题。此外,GC 的优点之一是以较慢的收集为代价的快速分配。

我认为您在产生碎片时遇到问题,这会使内存访问模式对 CPU 产生问题,因为它可能需要过于频繁地使其缓存无效。大多数 GC 算法不会以最佳方式回收空间。

由于您的工作集是有限且可预测的,您可能希望使用预先分配的对象池。您可能还想使用引用计数来避免大量手动内存管理。从技术上讲,它仍然是 GC,但不是 GC 的常识。

不过,我认为性能不会受到您管理内存的方式的太大影响,而是您实际使用和访问它的方式。您的分析器很可能有明确的答案。

【讨论】:

  • ++ 用于“池”概念。另一方面,引用计数?如果您在引用计数中的任何地方有任何错误,都很难找到。
  • Mike:在这种情况下实现引用计数并不难。池对象本身不包含引用。而且我没有看到java标签。
  • 不幸的是,我的分析器给了我一个完全废话的答案,而且我已经在 SO 上问过一个问题。我知道一两件事关于剖析,但在这种情况下我失败了,我将尝试像 VTune 这样的重型火炮......
  • @jkff:我的回答是——分析器就是这样。这是一些真正的重型火炮:stackoverflow.com/questions/406760/…
【解决方案2】:

对象分配有两个不同的方面。首先是找到一个合适的内存区域——对于当今的垃圾收集器来说,这通常非常快(大约是机器周期的十分之一)。

第二个是你分配的对象的初始化。由于您在 Java 中分配的所有内容都已初始化,因此初始化成本很容易超过分配成本(最简单、最小的对象除外)。还有更多。由于初始化需要写入新对象占用的整个内存区域(例如,如果分配“新字节 [1

如果您对每个数组进行的处理相对较少,那么这些效果可能会严重影响代码的性能。这可以通过一遍又一遍地重复使用相同的数组来部分避免,但它通常会使程序逻辑更加复杂。通常也不容易确定缓存垃圾是否真的是罪魁祸首。从您的问题中提供的少量信息中无法说出。

【讨论】:

    【解决方案3】:

    您的虚拟机是否尝试汇集字符串?我曾经听说过,IBM 的 VM 做了类似字符串实习的事情,但动态(不知道它是否属实)也许你的 VM 正在尝试做额外的工作来构建字符串内部的内部数据结构。

    您是否正在做类似byte b[] = new byte[100]; String s = new String(b); 的事情?您可以尝试不分配 String 对象,而是分配一些引用 byte[] 的随机对象(用于比较)。

    【讨论】:

    • 是的,我正在做一些类似于您显示的代码的操作。但出于各种原因,我需要这些字符串。
    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    相关资源
    最近更新 更多