#java #arrays
#java #массивы
Вопрос:
Я String[] inputMsg
объявил вне цикла и внутри цикла, который у меня есть inputMsg = new String[someSize];
, поскольку цикл может повторяться много раз, я обнаружил, что создание new String[someSize]
каждый раз действительно расточительно, поэтому на каждой итерации цикла я хотел бы удалить это выделение памяти или удалить его содержимое, чтобы inputMsg
оно было null
. Как это можно сделать на Java?
Комментарии:
1. создание массива чего угодно будет иметь минимальное влияние на объем выделенной памяти. Если ваш массив не имеет длины 1000, было бы глупо беспокоиться.
Ответ №1:
Зачем объявлять его вне цикла?
for (...) {
String[] inputMsg = new String[someSize];
...more code...
}
GC позаботится об освобождении памяти. Если GC окажется узким местом, и у вас есть цифры, чтобы доказать это, тогда мы можем поговорить еще немного. Но, оказывается, большинство GC довольно эффективны при восстановлении недолговечных объектов.
Комментарии:
1. Цикл находится внутри серверного приложения, которое получает сообщения из сокета, и каждое сообщение я выделяю новую память в «inputMsg»
2. Если вы имеете дело с сервером, и на самом деле, вероятно, он будет сильно загружен, вам нужно много узнать о внутренней работе Java heap management — достаточно, чтобы вы рассказывали нам, как все работает, а не наоборот.
Ответ №2:
Вы не удаляете объекты в Java, вы удаляете ссылки на них и ждете, пока сборщик мусора их соберет.
Если у вас есть String[] (т. Е. Массив строк), Вы можете попытаться повторно использовать его (особенно, если старый и новый массивы имеют одинаковый размер), но это лучшее, что вы собираетесь сделать.
Если вы хотите иметь возможность добавлять что-либо в массив (изменять его размер) с течением времени, вам не следует использовать обычный массив типа [], а следует использовать вектор или один из других объектов коллекции.
Комментарии:
1. В большинстве случаев они не будут одинакового размера, поскольку на первой итерации он может иметь размер 2, а на второй итерации он может быть размером 5… вот почему я хочу избавиться от ссылки, прежде чем выделять новую память.
2. Как насчет всех строк в массиве или всех других строк, которые вы создаете здесь и там? Вы их удаляете??
Ответ №3:
Вы не можете удалить что-либо в java вручную. Это автоматически выполняется сборщиком мусора. Он выполняется время от времени или если требуется больше памяти. Вы не можете повлиять на это.
Комментарии:
1. Ну … вы можете повлиять на это. System.gc()
2. Да, но было бы полной глупостью вызывать GC после каждого цикла создания String[] . (И поскольку он так часто используется неправильно, он часто отключается.)
Ответ №4:
Вы должны иметь возможность принудительно собирать мусор с помощью System.gc() или Runtime.gc(). Однако я настоятельно не рекомендую этого делать. Почему вы хотите, чтобы память освобождалась быстро? Есть ли конкретная причина?
Комментарии:
1. каждая итерация цикла — это новое сообщение, которое я получаю от сокета, и на каждой итерации оно может быть разных размеров
2.
System.gc()
не может принудительно собирать мусор, он может только предложить это.3. Да, я буду первым, кто признает, что я не очень много знаю о Java. Поскольку C # очень похож на Java, я нахожу, что по крайней мере некоторые знания C # косвенно являются знаниями Java. В .NET GC. Collect() вызывает асинхронную сборку данных, и вы действительно можете принудительно выполнить ее с помощью GC.WaitForPendingFinalizers() после GC. Сбор вызова. (На самом деле, у них есть некоторое «обнаружение злоупотреблений», которое будет подавлять избыточные GC.) Заметка для себя: «C #» ! = «Java» =)
Ответ №5:
Рассматривали ли вы возможность использования LinkedList вместо String[] ?