Ну, как указано в одном из комментариев, это ваш код, а не Java виноват в оттоке памяти.Итак, давайте посмотрим, что вы написали этот код, который создает безумно большую строку из StringBuffer.Вызывает toString () для него.Затем вызывает substring () для этой безумно большой строки, которая находится в цикле, и создает новые строки a.length ().Затем делает некоторые ненужные в массиве, которые действительно будут работать чертовски быстро, так как объект не создается, но в конечном итоге записывает в истину те же 5-6 мест в огромном массиве.Тратить много?Так что вы думаете, что произойдет?Отключите StringBuffer и используйте StringBuilder, поскольку он не полностью синхронизирован, что будет немного быстрее.
Хорошо, вот где ваш алгоритм, вероятно, тратит свое время.Посмотрите, как StringBuffer выделяет внутренний массив символов для хранения вещей каждый раз, когда вы вызываете append ().Когда этот массив символов полностью заполняется, он должен выделить больший массив символов, скопировать весь этот мусор, который вы только что написали ему, в новый массив, а затем добавить то, с чем вы изначально его называли.Таким образом, ваш код выделяет заполнение, выделяет больший кусок, копирует этот мусор в новый массив, а затем повторяет этот процесс до тех пор, пока он не сделает это 1000000 раз.Вы можете ускорить это, предварительно выделив массив символов для StringBuffer.Примерно это 10000000 * "sfdisdf" .length ().Это не даст Java создавать тонны памяти, которые она просто сбрасывает снова и снова.
Далее следует беспорядок compareAsSet ().Ваша строка String chr = a.substring (i, i);создает новые строки a.length () раз.Ну, так как вы используете a.substring (i, i) - это только символ, который вы могли бы просто использовать charAt (i), тогда выделение не происходит.Также есть опция CharSequence, которая не создает новую строку с собственным массивом символов, а просто указывает на исходный базовый символ [] со смещением и длиной.String.subSequence ()
Вы подключаете этот же код к любому другому языку, и он тоже будет отстой.На самом деле я бы сказал, гораздо хуже.Просто попробуйте это C ++ и посмотрите, будет ли оно значительно хуже, чем Java, если вы выделите и освободите это так много.См. Распределение памяти Java намного быстрее, чем C ++, потому что все в Java выделяется из пула памяти, поэтому создание объектов происходит на порядок быстрее.Но есть пределы.Кроме того, Java сжимает память, если она становится слишком фрагментированной, а C ++ - нет.Таким образом, по мере того, как вы выделяете память и выкидываете ее, точно так же, вы, вероятно, рискуете фрагментировать память в C ++.Это может означать, что ваш StringBuffer может исчерпать способность расти достаточно большим, чтобы закончить, и может произойти сбой.
Фактически, это также может объяснить некоторые проблемы с производительностью GC, потому что он должен сделать пространство более непрерывным блоком, достаточно большим после удаления большого количества мусора.Так что Java не только очищает память, но и сжимает адресное пространство памяти, чтобы он мог получить достаточно большой блок для вашего StringBuffer.
В любом случае, я уверен, что вы просто тестируете шины, но тестируетес таким кодом не очень хорошо, потому что он никогда не будет работать хорошо, потому что это нереальное распределение памяти.Вы знаете старую пословицу «Мусор в мусоре».И вот что у тебя есть Мусор.