Самый быстрый способ освободить память от stringbuilder

Это может звучать легкомысленно, но PrintStream печатает на OutputStream, а PrintWriter печатает на Writer. Хорошо, я сомневаюсь, что у меня появятся какие-то баллы за то, что я заявляю очевидное. Но есть еще.

Итак, в чем разница между OutputStream и Writer? Оба являются потоками, причем основным отличием является OutputStream - поток байтов, а Writer - поток символов.

Если OutputStream имеет дело с байтами, как насчет PrintStream.print(String)? Он преобразует символы в байты, используя кодировку платформы по умолчанию. Использование кодировки по умолчанию, как правило, плохо, поскольку это может привести к ошибкам при переходе с одной платформы на другую, особенно если вы создаете файл на одной платформе и потребляете его на другом.

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

Зачем беспокоиться о PrintStream в JDK, поскольку основной целью является запись символов, а не байтов? PrintStream предшествует JDK 1.1, когда введены потоки символов Reader / Writer. Я полагаю, что Солнце бы устарело PrintStream, если бы только тот факт, что он так широко используется. (В конце концов, вы не захотите, чтобы каждый вызов System.out генерировал устаревшее предупреждение api! Также, изменение типа от PrintStream до PrintWriter в стандартных потоках вывода нарушило бы существующие приложения.)

3
задан Brian Tompsett - 汤莱恩 18 January 2019 в 10:58
поделиться

5 ответов

Возможное решение включает в себя 3 шага:

  1. вызов sb.setLength(0). Это установит внутреннюю длину строителя строки на 0 и потребуется для шага 2.
  2. Звоните sb.trimToSize(). Это заменит массив value новым усеченным массивом, в нашем случае char[] размера 0
  3. sb = null удалит вашу ссылку на StringBuilder.

Если компоновщик строк используется только вами и не передается нигде, это должно сделать предыдущий массив value и компоновщик строк eglibe для сборки мусора.

Хотя когда это действительно произойдет, все еще зависит от JVM, и поэтому «самый быстрый путь», вероятно, не возможен, поскольку на самом деле он довольно случайный.

0
ответ дан Lino 18 January 2019 в 10:58
поделиться

Единственный безопасный способ гарантировать, что StringBuilder подходит для сборки мусора, такой же, как и все объекты: уничтожить все ссылки на него. Это означает, что нужно явно установить его на null или позволить ему выпасть из области видимости.

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

Другие предложенные вами варианты не гарантируют освобождение всей памяти, если вы не углубились в код и не уверены, что полностью очищаете состояние объекта. Вот почему обычно намного лучше просто обнулить всю ссылку на объект и начать все сначала, если вы хотите убедиться, что все «чисто».

0
ответ дан Mike Thomsen 18 January 2019 в 10:58
поделиться

Просто позвольте объекту StringBuilder выйти из области видимости (в закрывающей фигурной скобке) и не загромождайте свой код ненужными операторами, пытаясь заставить сборщик мусора выполнять свою работу быстрее. Когда объект StringBuilder выходит из области видимости, он становится пригодным для сборки мусора. Держите ваш исходный код в чистоте.

0
ответ дан Klitos Kyriacou 18 January 2019 в 10:58
поделиться

Все просто: иди с

sb = null;

и забудь обо всем остальном.

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

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

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

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

Все остальное пахнет преждевременной оптимизацией!

0
ответ дан GhostCat 18 January 2019 в 10:58
поделиться

Если вы действительно хотите, чтобы память высвобождалась как можно быстрее, вам нужно искать опции GC, а не код.

Подробный анализ вариантов GC для этой цели выходит за рамки того, что может здесь уместно поместиться, но, в частности, новый GC Shenandoah можно настроить так, чтобы он был гораздо более агрессивным в освобождении памяти, чем G1 или одновременная отметка / развертка, так что это, вероятно, то, что вы хотели бы использовать. Вы можете указать это с помощью -XX:+UseShenandoahGC. (На данный момент это специфично для OpenJDK и является экспериментальным, но если вам нужно поведение, к которому вы стремитесь, это то, что вам нужно.)

Для быстрого времени выпуска вы можете использовать небольшое значение для [ 111] и ShenandoahGuaranteedGCInterval. Меньшие значения здесь (в широком смысле) будут запускать ГХ чаще и агрессивнее, следовательно, с использованием большего количества циклов ЦП - но эффект, который вам нужен, будет высвобожден невероятно быстро по сравнению с предыдущими воплощениями ГК. 118]

Если вы просто хотите убедиться, что память освобождена, чтобы она подходила для быстрого сбора мусора, то вам просто нужно убедиться, что все ссылки на этот StringBuilder установлены в ноль в ближайшее время возможность. Однако даже в этом случае я рекомендую вам профилировать и проверить, нужно ли вам делать это явно - во многих случаях JVM достаточно умна, чтобы помечать объекты как подходящие для GC, даже если они технически все еще находятся в области действия ( до тех пор, пока он может видеть, что на них больше нет ссылок на оставшуюся часть этой области.)

0
ответ дан Michael Berry 18 January 2019 в 10:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: