Самый быстрый способ освободить память от stringbuilder - PullRequest
0 голосов
/ 17 января 2019

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

 StringBUilder sb = new StringBuilder();
 sb.apppend(maximum value possible);

Ниже приведены фрагменты кода, которые я попытался освободить из памяти как можно быстрее и сделать объект пригодным для сбора мусора

Вариант 1:

sb = null;

Насколько я понимаю, все данные в строителе строк будут удалены, и объект будет иметь право на сборку мусора, как только он будет запущен, но память текста, занимаемая строителем строк, будет освобождена. Также будет ли удалено строковое значение в нем из кучи или оно будет сохранено в пуле строк?

Вариант 2:

 sb.setLength(0);

Это сбросит длину строителя строк, но это не будет сбор мусора

Вариант 3:

 sb.delete(0,sb.length());

Это сбросит компоновщик строк, удалив все данные в нем, но он не будет собирать мусор

Вариант 4:

 sb.delete(0,sb.length());
 sb = null;

Это сбросит компоновщик строк, а также сделает его пригодным для сборки мусора?!

Ответы [ 5 ]

0 голосов
/ 17 января 2019

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

0 голосов
/ 17 января 2019

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

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

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

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

0 голосов
/ 17 января 2019

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

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

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

0 голосов
/ 17 января 2019

Простой: перейти с

sb = null;

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

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

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

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

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

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

0 голосов
/ 17 января 2019

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

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

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

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

...