java.lang.OutOfMemoryError, когда осталось много памяти (94 ГБ / 200 ГБ Xmx) - PullRequest
0 голосов
/ 24 ноября 2018

Я пытаюсь создать большие файлы 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 ГБ пространства подкачки.

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

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

1 Ответ

0 голосов
/ 25 ноября 2018

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

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

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

...