1

假设您正在使用一个简单的类并且对象创建并不繁重:

class Simple {
  public final int data1;
  public final float data2;
  ...
}

您必须不断地将简单对象放入队列中:

queue.add(new Simple(123,123f,...));

使用 Object-Pool 并更改 Simple-Class 可修改类是否更快?我希望不是。

4

2 回答 2

6

一般来说,不,它不会更快。如果您将 JVM 配置为使用“吞吐量”GC,您将通过不尝试回收对象获得更好的性能。仅当您“内存受限”或 GC 暂停有问题时才值得考虑对象池。(根据世代假设,随着垃圾与非垃圾的比例增加,垃圾收集对象的摊销成本趋于零,特别是如果对象“年轻时死去”。)

实际上:

  • 如果应用程序是多线程的,对象池很可能是并发瓶颈,并且

  • “有效不可变”对象的突变可能需要额外的开销和/或额外的同步。


如果对象创建速率是“每秒大约 20 个对象”,那么使用对象池不太可能对性能产生显着影响,即使它产生了改进(我对此表示怀疑)。

算一算。

  • 如果对象大小为SimpleN 字节,并且您每秒分配 M,您可以估计每秒分配的字节数。

  • 如果您的“年轻空间”是 Y MB,则根据该分配率触发 GC 需要 T 秒。

  • 如果“年轻空间”GC 对于大小为 Y 的空间平均占用 G ms,您可以估计假设可以节省的时间的上限……假设对象池的相关开销为零。

  • 实际节省的费用会更少,因为“零开销”假设是不现实的。

事实上,做一个“年轻空间”系列所花费的时间不仅仅取决于它的大小。它还取决于需要保留的非垃圾量。(保留的非垃圾越少越好!)这会使 GC 开销难以估计。但是,如果您已经在没有对象池的情况下编写了应用程序,则可以测量具有典型工作负载的应用程序的平均“年轻空间”收集时间,然后将其插入上面的计算中。

于 2015-08-19T15:00:31.913 回答
1

如果您确实在创建一些重对象或者您有其他要求指定对象池的需要,则对象池是有意义的。否则,我只会创建新对象并依靠 JVM 来摆脱所有不需要的对象(请记住首先删除/重新分配对不需要对象的引用)

于 2015-08-19T14:57:57.530 回答