无法在Java中创建长度为7M的类型变量的LinkedList

无法在Java中创建长度为7M的类型变量的LinkedList,java,linked-list,Java,Linked List,我试图创建一个非常大的链表,如下所示,但它在maven中作为单元测试运行失败。已经通过运行set MAVEN_OPTS=-Xmx4096m设置了堆大小,我正在windows中运行 在将大约600万个长项目插入列表后,代码失败。为什么?考虑到长类型是8字节,6M长的类型变量只有48M字节。即使Java对象有一些额外的隐藏字段,它也不应该这么早就失败 int N = 100000000; try { LinkedList<Long> buffer = new

我试图创建一个非常大的链表,如下所示,但它在maven中作为单元测试运行失败。已经通过运行set MAVEN_OPTS=-Xmx4096m设置了堆大小,我正在windows中运行

在将大约600万个长项目插入列表后,代码失败。为什么?考虑到长类型是8字节,6M长的类型变量只有48M字节。即使Java对象有一些额外的隐藏字段,它也不应该这么早就失败

 int N = 100000000;

    try {

        LinkedList<Long> buffer = new LinkedList<Long> ();

        for(int i=0;i<N;++i) {
            buffer.add((long)i);

            if (i % 1000000 == 0) {
                System.out.println("added " + i);

            }
       }
   catch(Exception e)
   {...}

别忘了我的记忆

LinkedList$Entry

别忘了我的记忆

LinkedList$Entry

列表中的每个条目都是一个单独的对象,引用了上一个和下一个节点以及当前值

如果我们假设每个引用8个字节,对象开销为16个字节,这意味着对于每个条目:

条目对象:40字节3个引用+开销 长对象:24字节数据+开销 所以在60万条参赛作品之后,大约3.84亿条。。。你还是应该接受的。根据您的JVM,我希望引用大小和每个对象的开销也会更低

我想知道您的MAVEN_选项是设置在错误的位置,还是出于某种原因没有用于JVM参数。我刚刚试着在我的Windows机器上运行它,而不是作为一个单元测试——只是作为一个主要方法,使用JVM默认分配,它在我输入了600万条之后也失败了。使用-Xmx1024M,它可以获得2500万个条目,这表明开销比我上面估计的要小。不过,我使用的是32位虚拟机


这当然表明您的MAVEN_OPTS没有做您想做的事情…

列表中的每个条目都是一个单独的对象,引用了上一个和下一个节点以及当前值

如果我们假设每个引用8个字节,对象开销为16个字节,这意味着对于每个条目:

条目对象:40字节3个引用+开销 长对象:24字节数据+开销 所以在60万条参赛作品之后,大约3.84亿条。。。你还是应该接受的。根据您的JVM,我希望引用大小和每个对象的开销也会更低

我想知道您的MAVEN_选项是设置在错误的位置,还是出于某种原因没有用于JVM参数。我刚刚试着在我的Windows机器上运行它,而不是作为一个单元测试——只是作为一个主要方法,使用JVM默认分配,它在我输入了600万条之后也失败了。使用-Xmx1024M,它可以获得2500万个条目,这表明开销比我上面估计的要小。不过,我使用的是32位虚拟机


这当然表明你的MAVEN_OPTS没有做你想做的事情…

LinkedList是存储一系列长数据的最内存效率低下的方法。您有一个长对象,它比普通长对象大约3倍,您有一个链接列表条目,它是双链接的,使其比普通长对象大约5倍


我建议您使用long[]或类似于TLongArrayList的包装器,对于大型集合,它每长使用几乎8个字节。它也会更快

LinkedList是存储一系列长数据的内存效率最高的方法。您有一个长对象,它比普通长对象大约3倍,您有一个链接列表条目,它是双链接的,使其比普通长对象大约5倍


我建议您使用long[]或类似于TLongArrayList的包装器,对于大型集合,它每长使用几乎8个字节。速度也会更快

+1:如果他的最大大小为-Xmx4096m,则他在64位JVM上,使每长的大小为72+32或104字节。使用-XX:+UseCompressedOops意味着大小与32位JVM相同,但我相信他使用了错误的数据结构。@Peter:你从哪里得到72+32?即使有一个24字节的开销,也会是48+32,不是吗?嗯,72是不正确的。40-48更接近。我应该测试它。用64位JVM测试它大约48字节。谢谢。事实证明MAVEN_选项对junit测试没有帮助。我为surefire修改了POM.xml并添加了以下行,然后它就工作了:pertest-Xms1024m-Xmx2048m false+1:如果他的最大大小是-Xmx4096m,那么他就在64位JVM上,使得每长的大小为72+32或104字节。使用-XX:+UseCompressedOops意味着大小与32位JVM相同,但我相信他使用了错误的数据结构。@Peter:你从哪里得到72+32?即使有一个24字节的开销,也会是48+32,不是吗?嗯,72是不正确的。40-48更接近。我应该测试它。用64位JVM测试它大约48字节。谢谢。事实证明MAVEN_选项对junit测试没有帮助。我修改了surefire的POM.xml并添加了以下行,然后它就可以工作了:pertest-Xms1024m-Xmx2048m false