Java 中的对象池
2022-09-03 08:26:35
维护一个常用对象池并从池中抓取一个而不是创建一个新对象的利弊是什么?类似于字符串暂存,只是所有类对象都可以这样做。
例如,它可以被认为是好的,因为它节省了gc时间和对象创建时间。另一方面,如果从多个线程使用,它可能会成为同步瓶颈,需要显式解除分配并引入内存泄漏的可能性。通过占用可以回收的内存,它会给垃圾回收器带来额外的压力。
维护一个常用对象池并从池中抓取一个而不是创建一个新对象的利弊是什么?类似于字符串暂存,只是所有类对象都可以这样做。
例如,它可以被认为是好的,因为它节省了gc时间和对象创建时间。另一方面,如果从多个线程使用,它可能会成为同步瓶颈,需要显式解除分配并引入内存泄漏的可能性。通过占用可以回收的内存,它会给垃圾回收器带来额外的压力。
优化的第一定律:不要这样做。第二定律:不要这样做,除非你真的已经测量并知道你需要优化和在哪里优化的事实。
只有当对象的创建成本非常高,并且它们实际上可以重用(您只能使用公共操作将状态重置为可以重用的东西),它才是有效的。
你提到的两个收益并不真实:java中的内存分配是免费的(成本接近10个cpu指令,这没什么)。因此,减少对象的创建只会节省您在构造函数中花费的时间。对于可以重用的真正重物(数据库连接,线程)而不进行更改,这可能是一个好处:您重用相同的连接,相同的线程。
GC时间不会减少。事实上,情况可能会更糟。对于移动分代 GC(Java 是或高达 1.5),GC 运行的成本由活动对象的数量决定,而不是由释放的内存决定。活动对象将被移动到内存中的另一个空间(这就是内存分配如此之快的原因:每个GC块内的可用内存是连续的)几次,然后被标记为旧并移动到旧一代内存空间中。
编程语言和支持,如GC,在设计时牢记了常见用法。如果您在许多情况下避开常见用法,则最终可能会遇到效率较低的更难阅读的代码。
除非创建对象的成本很高,否则我不会打扰。
好处:
缺点:
您是否有想要解决的实际问题,或者这是推测性的?我不会考虑做这样的事情,除非你有基准测试/配置文件运行显示存在问题。