通过Goetz的"Java Concurrency in Practice“一书,他提出了一个反对使用对象池的案例(第11.4.7节)-主要论点:
1) Java中的分配比C的malloc快2)从池中请求对象的线程需要代价高昂的同步
我的问题并不是分配很慢,而是周期性的垃圾收集在响应时间中引入了异常值,这些异常值可以通过减少对象池来消除。
在使用这种方法时,有没有什么我看不到的问题?从本质上讲,我是在跨线程对对象池进行分区...
发布于 2010-09-22 02:42:47
如果它是线程本地的,那么你可以忘记这一点:
2)从池中请求对象的线程需要代价高昂的同步
由于是线程本地的,您不需要担心从池本身检索的同步。
发布于 2010-09-22 02:52:41
在Java1.4中,对象分配是相对昂贵的,因此即使是简单对象的对象池也可以有所帮助。然而,在Java5.0中,对象分配得到了显著的改进,然而同步仍然有一段路要走,这意味着对象分配比同步更快。也就是说,删除对象池在许多情况下提高了性能。在Java 6中,同步已经得到了改进,在简单的情况下,对象池可以对性能产生很小的影响。
避免简单对象池是一个好主意,因为它更简单,而不是出于性能原因。
对于更复杂/更大的对象,对象池在Java 6中可能很有用,即使您使用同步。例如,套接字、文件流或数据库连接。
发布于 2010-09-22 02:56:15
(sun的) GC扫描活动对象。假设在典型的java程序运行时中,死对象要比活对象多得多。它标记活动的对象,并处理其余的对象。
如果你缓存了很多对象,它们都是活动的。如果你有几个GB的这样的对象,GC将浪费大量的时间对它们进行徒劳的扫描。长时间的GC暂停会使您的应用程序瘫痪。
缓存一些东西只是为了让它成为非垃圾的,这对GC没有帮助。
这并不是说缓存是错误的。如果你有15G的内存,而你的数据库是10G的,为什么不把所有东西都缓存在内存中,这样响应速度就快了。注意,这是为了缓存一些本来会很慢的东西。
为了防止GC无果地扫描10G缓存,缓存必须在GC的控制范围之外。例如,使用‘memcached’,它位于另一个进程中,拥有自己的缓存优化GC。
最新消息是Terracotta的BigMemory,它是一个纯java解决方案,可以做类似的事情。
线程本地池的一个示例是sun的直接ByteBuffer池。当我们调用
channel.read(byteBuffer)如果byteBuffer不是“直接”的,则必须在幕后分配一个“直接”的a,用于与操作系统进行数据通信。在网络应用程序中,这样的分配可能非常频繁,丢弃刚刚分配的一个,然后在下一条语句中立即分配另一个,似乎是一种浪费。sun的工程师显然不太信任GC,他们创建了一个“直接”ByteBuffers的线程本地池。
https://stackoverflow.com/questions/3763353
复制相似问题