Повторные вызовы замены приводят к java.lang.OutOfMemoryError - PullRequest
2 голосов
/ 26 октября 2019

Я занимаюсь массовой обработкой очень больших файлов. Я вызываю следующий метод для каждого URI в каждой строке:

public String shortenUri(String uri) {
    uri = uri
            .replace("http://www.lemon-model.net/lemon#", "lemon:")
            .replace("http://babelnet.org/rdf/", "bn:")
            .replace("http://purl.org/dc/", "dc:")
            .replace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf:");
    return uri;
}

Странно, это приводит к следующей ошибке:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.regex.Pattern$BnM.optimize(Pattern.java:5411)
at java.util.regex.Pattern.compile(Pattern.java:1711)
at java.util.regex.Pattern.<init>(Pattern.java:1351)
at java.util.regex.Pattern.compile(Pattern.java:1054)
at java.lang.String.replace(String.java:2239)
at XYZ.shortenUri(XYZ.java:217)

Я увеличил Xms и Xmxно это не помогло. Странно, я также не мог наблюдать увеличение использования памяти при мониторинге процесса. Любые предложения по увеличению производительности и потребления памяти здесь?

1 Ответ

0 голосов
/ 26 октября 2019

Цитата из Oracle :

Чрезмерное время GC и OutOfMemoryError

Параллельный сборщик сгенерирует OutOfMemoryError, если слишком многовремя тратится на сборку мусора: если более 98% от общего времени уходит на сборку мусора и восстанавливается менее 2% кучи, генерируется ошибка OutOfMemoryError. Эта функция предназначена для предотвращения запуска приложений в течение длительного периода времени при небольшом прогрессе или его отсутствии, поскольку куча слишком мала. При необходимости эту функцию можно отключить, добавив в командную строку параметр -XX: -UseGCOverheadLimit.

  1. Первое, что вы можете попробовать, это еще больше увеличить размер кучи, дляНапример, для нескольких ГБ с -Xmx4G.
  2. Другой вариант может состоять в том, чтобы предотвратить создание слишком большого количества объектов, не используя метод replace. Вместо этого вы можете создавать Pattern и Matcher объекты по мере необходимости (см. Ниже).
  3. Третий вариант, который я вижу, - отключить эту функцию вместе с -XX:-UseGCOverheadLimit

    private static final Pattern PURL_PATTERN = Pattern.compile("http://purl.org/dc/");
    // other patterns
    
    public static String shortenUri(String uri) {
        // other matchers
        Matcher matcher = PURL_PATTERN.matcher(uri);
        return matcher.replaceAll("dc:");
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...