大型Java列表的性能较差

杰伊·哈克(Jay Hacker):

我正在尝试使用Java将大文本语料库读入内存。在某个时候,它撞到了墙,只是垃圾不断地收集。我想知道是否有人有击败Java的GC到具有大型数据集的提交方面的经验。

我正在读取一个8 GB的英文文本文件,格式为UTF-8,一行中只有一个句子。我想split()在空格上的每一行,并将生成的String数组存储在中,以ArrayList<String[]>进行进一步处理。这是一个显示问题的简化程序:

/** Load whitespace-delimited tokens from stdin into memory. */
public class LoadTokens {
    private static final int INITIAL_SENTENCES = 66000000;

    public static void main(String[] args) throws IOException {
        List<String[]> sentences = new ArrayList<String[]>(INITIAL_SENTENCES);
        BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
        long numTokens = 0;
        String line;

        while ((line = stdin.readLine()) != null) {
            String[] sentence = line.split("\\s+");
            if (sentence.length > 0) {
                sentences.add(sentence);
                numTokens += sentence.length;
            }
        }
        System.out.println("Read " + sentences.size() + " sentences, " + numTokens + " tokens.");
    }
}

看起来很干,对吗?您会注意到我什至对我的东西进行了预先调整ArrayList我的句子少于6600万个,令牌少于13亿个。现在,如果您不妨参考一下Java对象大小参考和铅笔,那么您将发现,这大约需要:

  • 66e6 String[]引用@ 8个字节ea = 0.5 GB
  • 66e6个String[]对象@ 32个字节ea = 2 GB
  • 66e6个char[]对象@ 32个字节ea = 2 GB
  • 1.3e9 String引用@ 8个字节ea = 10 GB
  • 1.3e9 Strings @ 44个字节ea = 53 GB
  • 8e9 chars @ 2个字节ea = 15 GB

83 GB(您会注意到我确实确实需要使用64位对象大小,因为压缩的OOP无法帮助我处理> 32 GB的堆。)我们很幸运地拥有一台具有128 GB RAM的RedHat 6机器,所以我开了pv giant-file.txt | java -Xmx96G -Xms96G LoadTokens为了安全起见,从Java SE 1.6.0_29套件中安装了Java HotSpot(TM)64位服务器VM(内部版本20.4-b02,混合模式),然后在观看时反冲top

在不到输入一半的地方,大约有50-60 GB RSS,并行垃圾收集器启动了1300%的CPU(16个proc盒),并且读取进度停止。然后它又增加了几GB,然后进度停止了更长的时间。它已填满96 GB,但尚未完成。我已经放了一个半小时了,做GC只消耗了大约90%的系统时间。那似乎是极端的。

为了确保我没有发疯,我整理了等效的Python(共两行;),它在大约12分钟和70 GB的RSS中运行完毕。

所以:我在做些蠢事吗?(除了通常低效的存储方式之外,我什至无济于事-即使我的数据结构很胖,只要它们适合,Java也不会令人窒息。)是否有神奇的GC建议?大堆?我确实尝试过-XX:+UseParNewGC,而且看起来甚至更糟。

杰伊·哈克(Jay Hacker):

-XX:+UseConcMarkSweepGC:在78 GB和12分钟内完成。(几乎与Python一样好!)谢谢大家的帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有没有针对Java在大型目录上行走时性能较差的解决方法?

MongoDB在具有50.000.000文档的大型集合上的写入性能较差

递归函数的性能较差

与Java相比,F#性能较差。我究竟做错了什么?

大型项目列表的Angular 2性能优化

Django ORM与原始SQL相比性能较差

RAID 5阵列的写入性能较差

BitmapCache在调整大小时性能较差

如何使用HHVM改善较差的阵列性能?

MySQL的内部双连接更新性能较差

Java列表可怕的添加性能

性能:遍历Java中的列表

添加到大型Java集合中,性能瓶颈

中大型结果集的Hibernate,JDBC和Java性能

调整在Java中读取大型InputStream的性能

JSF和Spring性能与较差的JSP性能

在大型列表中查找具有相同属性的对象-性能降低

性能-我应该同时使用数组和对象作为大型列表吗?

性能-比较Python中2个大型字符串列表的最快方法

在大型oracle表中搜索值列表时,能否获得良好的性能?

Guava Multimaps.filterKeys与NavigableMap.subMap()相比性能较差

带有突出显示的文本(标签)的JavaFX表性能较差

Gensim doc2vec文件流训练性能较差

为什么大量的递增运算符(++)的性能较差?

SQL Server内存优化表-与临时表相比性能较差

Oracle 12c中的子选择性能较差

Android上的Eclipse Paho MQTT客户端,性能较差

由于GCContextDrawImage调用可疑的调试函数,因此性能较差

与Mac OS X相比,Ubuntu的性能较差(硬件相同!)