Вопрос

У меня есть цикл, который порождает множество потоков.Эти потоки содержат, среди прочего, 2 (массивных) объекта StringBuilder.Затем эти потоки запускаются и делают свое дело.

Однако я заметил, что после определенного количества потоков я получаю странные сбои.Я знаю, что это из-за этих StringBuilder , потому что когда я уменьшаю их начальную емкость, я могу запустить намного больше потоков.Теперь для этих StringBuilders они создаются следующим образом в конструкторе объекта thread:

StringBuilder a = новый StringBuilder(30000);
StringBuilder b = новый StringBuilder(30000);

Точка, в которой обычно происходит сбой, составляет около 550 потоков, что приводит к чуть более чем 62 МБ.В сочетании с остальной частью программы используемая память, скорее всего, составляет 64 МБ, что, как я где-то читал в Интернете, было размером пула выделения памяти JVM по умолчанию.Я не знаю, правда это или нет.

Итак, есть ли что-то, что я делаю неправильно, что каким-то образом из-за дизайна я выделяю память неправильным образом?Или это единственный способ, и я должен сказать JVM увеличить свой пул памяти?Или что-то совсем другое?

Кроме того, пожалуйста, не советуйте мне устанавливать меньшую емкость, я знаю, что эти StringBuilders автоматически увеличивают свою емкость при необходимости, но я хотел бы иметь решение этой проблемы.

Это было полезно?

Другие советы

Если вы храните много информации в StringBuilder, собираетесь ли вы ссылаться на нее в какой-то момент?Если нет, то просто запишите его на другой носитель (БД, файл и т.д.).Программа располагает конечным объемом ресурсов, она не может одновременно отображать все состояния всей системы.-Xmx предоставит вам больше места для хранения в памяти, однако это не сделает ваши возможности хранения бесконечными.

Рассмотрите возможность использования ThreadPoolExecutor, и установите размер пула равным количеству процессоров на вашем компьютере.Создание большего количества потоков, чем процессоров, - это просто добавление накладных расходов.

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

Кроме того, вы можете уменьшить использование памяти, записывая свои строки в файлы вместо того, чтобы хранить их в памяти с StringBuilders.

Предположим, 1 МБ на поток.Это затраты оперативной памяти на создание каждого из них, сверх объема памяти, выделяемой его процессом.

Как сказал Грегори, дайте jvm несколько опций, таких как -Xmx.

Также рассмотрите возможность использования пула потоков или исполнителя, чтобы гарантировать, что одновременно выполняется только заданное количество потоков.Таким образом, объем памяти может быть ограничен без замедления (поскольку ваш процессор в любом случае не способен запускать 550 потоков одновременно).

И когда вы используете Исполнитель, создавайте StringBuilders не в конструкторе, а в методе run.

Вы можете использовать Файловый редактор чтобы вывести текст в файл, затем извлеките его обратно с помощью программы FileReader.Таким образом, вам нужно будет сохранить в памяти только имя файла, а не все содержимое строки.

Чтобы сократить количество потоков, вы можете использовать ExecutorService или просто использовать несколько потоков, которые считывают данные из очереди.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top