Я пытаюсь создать большие файлы RDF / HDT, что, в свою очередь, означает чтение больших файлов в память и т. Д. Теперь это не проблема, поскольку на сервере 516 ГБ памяти, из которых около 510 ГБ свободны.

Я использую библиотеку 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)

Я запускаю файл Jar с тегом -Xmx200G. Странно то, что когда вы смотрите «вверху», он показывает, что VIRT составляет 213G (как и ожидалось). Однако каждый раз, когда RES достигает примерно 94 ГБ, он вылетает с указанной выше ошибкой, что я считаю странным, поскольку для использования должно быть более 100 ГБ. Я посмотрел в этот вопрос, так как проблема кажется похожей на мою, хотя и в другом масштабе. Однако использование -verbose:gc и - XX:+PrintGCDetails, похоже, не дает мне никаких указаний относительно того, что не так, а также доступно около 500 ГБ пространства подкачки.

Однако, пожалуй, самым странным является то, что конкретный файл, с которым у меня есть проблемы, даже не самый большой. Для масштабирования он имеет около 83 миллионов троек для записи, а для других файлов до 200 миллионов троек не является проблемой. Я использую версию Java 1.8.0_66 и версию Ubuntu 14.04.3 LTS.

Итак, мой вопрос: может ли кто-нибудь объяснить, что я делаю неправильно? Мне кажется очень странным, что с большими файлами проблем нет, а вот с этим есть. Пожалуйста, дайте мне знать, если вам понадобится другая информация.

7
Chraebe 24 Ноя 2018 в 23:36

1 ответ

Лучший ответ

Из-за максимальной длины массива Java ByteArrayOutputStream не может содержать более 2 ГБ данных. Это верно независимо от вашего текущего объема оперативной памяти или ограничений памяти. Вот код, который вы ' повторное нажатие:

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

Вам придется переписать свой код, чтобы не пытаться хранить столько данных в одном массиве.

5
that other guy 24 Ноя 2018 в 21:22