向LinkedList添加节点会导致Java的非堆内存泄漏

时间:2017-10-10 02:38:43

标签: java memory garbage-collection heap

在尝试使用串行GC 的Java内存使用时,我注意到随着java.util.LinkedList<String>中节点数量的增加,堆不仅增长了,而且非堆内存用法也在不断增长。但是,对于ArrayList,只有堆增长,非堆内存随着堆的增长而保持不变。

为了测试这个,我运行了一个简单的程序,它会在无限循环中向LinkedList添加String个节点,当它抛出时(通过-XX:MaxHeapSize标志控制)OutOfMemoryError它会在catch块内无限循环。除了-XX:MaxHeapSize标志之外,我还使用了-XX:MaxMetaSpaceSize-XX:ReservedCodeCacheSize-Xshare=on标志,这些标志对此行为没有任何影响。我用不同的MaxHeapSize值保持它们的值不变。我还打开了Native Memory Tracking。我用ArrayList而不是LinkedList重复了相同的程序。为了测量堆内存使用情况,我注意到了NMT报告的已提交堆。为了获得非堆内存,我从smem报告的RSS中减去了堆内存。 该实验在 HotSpot 64位服务器VM 25.144-b01 OpenJDK 64位服务器VM 25.131-b11 上重复,并且具有类似的结果。

以下是我使用OpenJDK服务器VM记录的值(以MB为单位)。

对于LinkedList:

| MaxHeapSize | Heap | Non-heap |
| ----------- | ---- | -------- |
| 108.8       | 110  | 78.6     |
| 217.6       | 218  | 122.5    |
| 435.2       | 436  | 161.1    |
| 870.4       | 872  | 366.6    |
| 1305.6      | 1306 | 470.2    |

对于ArrayList:

| MaxHeapSize | Heap | Non-heap |
| ----------- | ---- | -------- |
| 108.8       | 110  | 34.0     |
| 217.6       | 218  | 32.6     |
| 435.2       | 436  | 33.4     |
| 870.4       | 872  | 37.2     |
| 1305.6      | 1306 | 37.7     |

查看java.utils.LinkedList<E>类的实现并不表示可能导致此行为的任何内容。

什么可能导致LinkedList和ArrayList之间的内存使用情况有所不同?

0 个答案:

没有答案