记一次LinkedList引起的内存爆炸

有一个程序,有一段逻辑中,会多次调用一个函数,其返回一个List,List中最多有1万个对象,该函数大概调用9次,但是多次调用后却占用了几个G的内存。

List中存的对象

TopResult是List中保存的对象,每个对象的大小是32字节,chefs和equipid指向的数组是复用的,占用内存不做考虑,recepeids指向的数组为new int[9],占用56字节,也就是一个TopResult对象占用88字节,1w个对象,也不过才859.375KB。

而整个函数中只有一个LinkedList,一个common-pool对象池(用来管理TopResult对象),然后剩下的都是一些int[],首先打印整个运行过程中 TopResult的创建次数, 9w多次,也不过几十M的大小而。

首先通过jvisualvm查看内存使用情况,发现有大量的Objec[]对象,这几个G的内存也都是被这些Objec[]占用了。

当时也怀疑是不是使用common-pool造成的,取消使用对象池后,内存情况并没有得到改善。

最后发现是因为是对LinikList调用了sort的锅。

Collections.sort(List<T> list, Comparator<?super T> c),而我传递的 list是一个LinkedList,然后LinkedList的sort方法继承自List接口中的sort方法,


List接口中的sort方法


LinkedList的toArray()

第一行this.toArray(),这个方法会创建一个Object[]数组。因为sort被调用次数太多,导致Object[]占用了几个G的内存。

我特意统计了下, sort方法被调用了 78684次,每一次调用创建一个Object[10000], 也就是 (4*10000+12)*78684=31474544208字节,2.9G的大小。 最后将LinikList改成ArrayList解决问题。

sort方法调用次数



至于为啥一开始使用LinkedList,因为有时候调用函数后,返回的List会为空,就想着LinkedList占用内存会少一点。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。