Это плохая практика назначить новый массив существующему массиву, чтобы "очистить" массив в Java?
поэтому в настоящее время я работаю над программой, которая должна иметь возможность работать с большим количеством данных, хранящихся в массивах, и ей нужен метод, чтобы очистить все в массиве. Для приведенного ниже примера, будет ли это плохо, чтобы сделать память мудрой? Я знаю, что сборщик мусора в конечном итоге очистит его для вас, но есть ли причина, по которой другой метод (например, цикл for и установка каждого значения в null) может быть лучше этого?
Object[] objArray = new Object[n];
/*Do some stuff with objArray*/
objArray = new Object[n]
в противном случае, это приведет к позвольте этой операции выполняться в O(1) Время против цикла for, который займет O (n).
6 ответов
Это плохая практика.
во-первых, назначение нового массива переменной фактически не "очищает" что-либо (подробнее об этом ниже).
Это лучшая практика:
objArray = null;
что делает исходный массив недоступным, и поэтому он будет (в конечном итоге) собранным мусором.
это также позволяет избежать ненужного выделения памяти, создавая пустой массив, который вы использовали для замены старого.
однако, ни один из вариантов "очищает" из исходного массива, который может представлять собой, хотя и небольшое, воздействие безопасности. Пока мусор не собран, содержимое массива может быть divinable, если содержимое памяти сбрасывается и т. д.
по-настоящему очистить массив:
Arrays.fill(objArray, null);
нет, это не плохая практика. Однако обнуление всех индексов массива, скорее всего, будет быстрее (технически это то, что называется детализацией реализации; но не стесняйтесь проверять это на вашей конкретной системе), потому что дополнительный шаг выделения новой памяти не нужен. Однако советую не становиться жертвой так называемой преждевременной оптимизации, так как это может привести к потере времени, если позже вы обнаружите, что вам нужно внести большие изменения. Кроме того, имейте в виду, что вы будете держать используя существующий объект array, любые другие части кода, ссылающиеся на него, также увидят изменения в нем.
технически, это действительно не имеет значения.
больше читабельности, и сообщение намерения.
вы видите, в настоящее время вы стремитесь сделать ваши объекты неизменяемые. Если что-то нельзя изменить, вы избегаете всевозможных проблем с несколькими потоками. Так что обновление ссылка на новый массив не совсем соответствует этому.
другой момент стоит упомянуть: если вы действительно хотите ясный массивы (по крайней мере для примитивных типов), вам лучше массив и сбросить все свои гнезда. (очевидно, что это невозможно для массивов ссылочных типов)
это совершенно нормально, так как вы используете "примитивный" массив вместо любой коллекции. Вы можете чувствовать себя неуверенно в выделении памяти из предыдущего массива, но не волнуйтесь, что GC очистит это для вас. Но при использовании API коллекций вы скорее вызываете:
yourCollection.clear()
другой подход, используемый ByteBuffer, состоит в том, чтобы сохранить исходный массив, оставить его содержимое в покое и перезаписать с самого начала. При использовании массива используйте индекс последнего обновленного элемента, чтобы избежать остатка массива. "Очистка" массива на самом деле ничего не дает, если только то, что обрабатывает массив, не ищет какое-то конкретное значение для указания конца содержимого.
типичные пользователи Java не должны беспокоиться об управлении памятью, если безопасность или производительность не являются явными узкими местами. См.по теме вопросы.
Если вам действительно нужно иметь способ "стереть" массив для вашей логики (i.e отметьте массив как reset), и поскольку вы собираетесь повторно использовать массив позже, вы можете
используйте логическое значение, чтобы пометить массив как "непригодный", пока он не будет заполнен снова (лучшее решение, если объекты внутри массива не потребляют слишком много памяти)
заполните его
null
вместо того, чтобы назначатьnull
к нему, чтобы избежать нескольких распределений массива (особенно еслиn
большой) в долгосрочной перспективе:Arrays.fill(objArray, null);
.