我的应用程序运行在HotSpot jvm 1.8.0_45上,打包好的8GB堆。应用程序尝试为新对象分配内存失败,并发生堆空间OOM错误。我查看了堆转储,发现大部分空间都被charCCufferCaches的T4CConnection实例占用。这个缓存为char数组保存了SoftReferences。我很惊讶SoftReferences在OOM之前没有发布。我再次检查是否有一个这个数组的硬引用,但没有找到一个。OOM错误和怪异的SoftReferences
为什么我的应用程序通过SoftReferences持有3GB字符数组时存在堆空间OOM? 为什么这个SoftReferences在应用程序需要新内存时不能发布? T4CConnection对象的
部分表示charBufferCache:用于字符数组
传入的引用在T4CConnection charBufferCache holded者:
什么时候被转储捕获?这可能是由于堆栈上的某些东西使数组保持活动状态,并且由于异常导致堆栈解开后,转储中并未反映该数组。而且,OOM的具体类型也很重要,例如,即使释放软引用后分配请求可能已满足,也可能发生超出一个的开销。使用+ HeapDumpOnOutOfMemoryError JVM选项创建了 – the8472
转储。我认为这个选项产生的快照应该包含OOM错误出现时的所有对象和引用。快照中是否有任何参考文献缺失的机会?另外,我的应用程序没有通过大帧消耗内存 - 它不会一次尝试分配2GB对象。 – nukie
是的,我认为这个选项确实包含了栈根。但OOME的确切类型仍然可能会有所作为。 – the8472