【问题标题】:java.lang.OutOfMemoryError when plenty of memory left (94GB / 200GB Xmx)java.lang.OutOfMemoryError 当剩余大量内存时(94GB / 200GB Xmx)
【发布时间】:2019-04-26 23:30:29
【问题描述】:

我正在尝试创建大型 RDF/HDT 文件,这又意味着将大型文件读入内存等。现在,这不是一个真正的问题,因为服务器有 516GB 内存,其中大约 510GB 是免费的。

我正在使用rdfhdt 库来创建文件,效果很好。但是,对于一个特定的文件,我不断收到 OutOfMemoryError,但没有真正的原因。这是堆栈跟踪:

 Exception in thread "main" java.lang.OutOfMemoryError
    at java.io.ByteArrayOutputStream.hugeCapacity(ByteArrayOutputStream.java:123)
    at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:117)
    at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
    at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
    at org.rdfhdt.hdt.util.string.ByteStringUtil.append(ByteStringUtil.java:238)
    at org.rdfhdt.hdt.dictionary.impl.section.PFCDictionarySection.load(PFCDictionarySection.java:123)
    at org.rdfhdt.hdt.dictionary.impl.section.PFCDictionarySection.load(PFCDictionarySection.java:87)
    at org.rdfhdt.hdt.dictionary.impl.FourSectionDictionary.load(FourSectionDictionary.java:83)
    at org.rdfhdt.hdt.hdt.impl.HDTImpl.loadFromModifiableHDT(HDTImpl.java:441)
    at org.rdfhdt.hdt.hdt.writer.TripleWriterHDT.close(TripleWriterHDT.java:96)
    at dk.aau.cs.qweb.Main.makePredicateStores(Main.java:137)
    at dk.aau.cs.qweb.Main.main(Main.java:69)

我正在运行带有标签-Xmx200G 的Jar 文件。奇怪的是,当查看“顶部”时,它显示 VIRT 为 213G(如预期的那样)。但是,每次 RES 爬升到大约 94GB 时,它都会因上述错误而崩溃,我认为这很奇怪,因为它应该有超过 100GB 的剩余空间可以使用。我查看了this 问题,因为问题似乎与我的问题相似,尽管规模不同。但是,使用 -verbose:gc 和 -XX:+PrintGCDetails 似乎并没有给我任何关于哪里出了问题的迹象,而且还有大约 500G 的可用交换空间。

然而,也许最奇怪的是,我遇到的特定文件甚至不是最大的文件。对于规模,它有大约 83M 三元组要写入,而对于其他文件,多达 200M 三元组不是问题。我使用的是 Java 版本 1.8.0_66 和 Ubuntu 版本 14.04.3 LTS。

所以我的问题是,是否有人可以解释我做错了什么?对我来说,较大的文件没有问题似乎很奇怪,但这个文件确实如此。如果您需要任何其他信息,请告诉我。

【问题讨论】:

  • 好奇(与之前删除的评论有关):如果增加到例如 -Xmx300G(从 200 增加),程序是否完成?这种情况下进程使用的最大内存是多少?
  • @user2864740 遗憾的是没有。我已经尝试了高达 -Xmx500G 并且它仍然无法运行(此时我想它无论如何都太高了)。总的来说,我尝试给它最多 200、250、300、400 和 500GB 的堆空间。
  • 看起来字典大小在内存中超过了最大值。对应Java结构的容量。你应该在 Github 上打开一个问题。有趣的是,这个文件和其他正在工作的文件有什么明显的区别吗?也许更大的文字,不同节点的数量等?
  • 你尝试过 HDT 的 C++ 实现吗?

标签: java linux memory out-of-memory rdf


【解决方案1】:

由于 Java 的最大数组长度,一个 ByteArrayOutputStream 不能容纳超过 2GB 的数据。无论您当前的 RAM 量或内存限制如何,这都是正确的。这里是the code you're hitting

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();

你必须重写你的代码以避免将这么多数据保存在一个数组中。

【讨论】:

    猜你喜欢
    • 2017-12-29
    • 2010-11-11
    • 2010-11-14
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多