Serialization Terracotta EhCache-并发修改在序列化期间创建巨大的字节数组

Serialization Terracotta EhCache-并发修改在序列化期间创建巨大的字节数组,serialization,ehcache,heap-dump,terracotta,ehcache-bigmemory,Serialization,Ehcache,Heap Dump,Terracotta,Ehcache Bigmemory,如果我的heapdump支配者树视图如下图所示,那么我是否可以假设堆的主要贡献者~1GB是Weblogic创建的线程实例?在该线程中,对ByteArrayOutputStream的引用是1GB的原因 后续问题:我是否可以假定这也是由于对象序列化造成的?可能是由第三条线的陶土触发的。不是因为它在Byarrayos旁边,而是因为在我们的代码中,序列化是唯一可以发生的地方?Ehcache在缓存超出堆的那一刻确实依赖于Java序列化 但是,它只会序列化您放入缓存中的内容。那么,有没有可能某些缓存的映射

如果我的heapdump支配者树视图如下图所示,那么我是否可以假设堆的主要贡献者~1GB是Weblogic创建的线程实例?在该线程中,对ByteArrayOutputStream的引用是1GB的原因


后续问题:我是否可以假定这也是由于对象序列化造成的?可能是由第三条线的陶土触发的。不是因为它在Byarrayos旁边,而是因为在我们的代码中,序列化是唯一可以发生的地方?

Ehcache在缓存超出堆的那一刻确实依赖于Java序列化


但是,它只会序列化您放入缓存中的内容。那么,有没有可能某些缓存的映射具有如此巨大的值甚至键呢?

支配者树表示,您有一个Weblogic线程,其中包含一个ByteArrayOutputStream和一个SerializerObjectOutputStream。Weblogic线程是当前处理请求的经典工作线程。现在它被困在了什么东西上

因此,这相当于

ByteArrayOutputStream in = new ByteArrayOutputStream();
Thread.wait();
该线程持有ByteArrayOutputStream,无法对其进行垃圾收集,因为该线程没有使用它

看到序列化程序,我觉得您当前正在从Ehcache磁盘或堆外反序列化


有没有可能您正在缓存中放置相当大的对象?正如@louis jacomet提到的,我们注意到了。

感谢您的回复,louis。我们使用的是分布式缓存Terracotta ehCache。在这种情况下,它是否每次在缓存中添加元素时都序列化?要在集群的所有节点中复制新元素?与其等待缓存大小超出堆,不如将堆用作本地热缓存,但对缓存的每次写入都会立即推送到集群。否则就没有一致性保证了。谢谢路易斯。我已经更新了正在讨论的图像,以显示支配树中的下一个对象。您可能会注意到它们都没有接近字节数组的大小。事实上,我们放在缓存中的对象是~2MB。序列化时会导致1GB字节数组大小吗?遗憾的是,回答更具体的问题需要查看对象的代码。您是否可能持有对某个共享对象的引用,而该引用会被序列化吞没。获取Ehcache配置也会有所帮助。最后,鉴于信息有限,问题可能完全是另外一个问题。你问起共享的东西很有趣。我们在特定线程中添加到缓存的对象也被另一个线程并行修改。这不是出于设计,而是由于一种不可预见的情况。然而,它是否真的会产生问题。例如,我们有一个带有列表的Employee对象。当一个线程在缓存中添加Employee对象e1时,另一个线程以某种方式获得e1引用并添加数量有限的任务。也许这就是我们的问题所在,但究竟是什么让2MB员工反对1GB呢?谢谢Henri的回复。你能帮我理解你怎么说它是从Ehcache反序列化的吗?它不是将对象序列化到bytearray,而不是将bytearray序列化到对象。我可以看到,在这个特定的线程中,我添加了一个大小为1MB的对象。但是线程大小在堆中显示为1GB。另一个可能有用的信息是,overflowToOffHeap设置为false。ehcache是否仍使用堆外资源?这是ehcache 2。我不是这个版本的专家,所以路易斯会准确回答。我之所以这么说是因为我在堆栈上看到了流和序列化程序。那么,它为什么这么大取决于ByteArrayInputStream来自哪里。