обнулить объект, который является частью Java ArrayList - PullRequest
3 голосов
/ 14 июля 2009

У меня есть список массивов:

private ArrayList<PerfStatBean> statFilterResults;

Я хочу повторить это как:

Iterator<PerfStatBean> statsIterator = statFilterResults.iterator();
while(statsIterator.hasNext()){
  i++;
  PerfStatBean perfBean = statsIterator.next();
  .........

Я хотел бы удалить компонент из statFilterResults после того, как я пробегу его внутри цикла while, чтобы освободить память. Я верю, что если я сделаю что-то вроде

 perfBean = null;

он не будет выполнять эту работу, поскольку ссылка на perfBean будет нулевой, но объект все еще будет в памяти.

Есть идеи?

Спасибо

Tam

Ответы [ 8 ]

3 голосов
/ 14 июля 2009

Это, вероятно, не очень хорошая оптимизация. Если требования к памяти велики, то, вероятно, вы не хотите сохранять их все в списке, во-первых, обрабатывать объекты по мере их создания.

Однако, принимая вопрос буквально, ListIterator.set - это метод для вас.

for (
    ListIterator<PerfStatBean> iter = statFilterResults.listIterator();
    iter.hasNext()
) {
    ++i;
    PerfStatBean perfBean = iter.next();
    iter.set(null);
    ...
}
2 голосов
/ 14 июля 2009

Почему бы просто не очистить список после его повторения?

Iterator<PerfStatBean> statsIterator = statFilterResults.iterator();
while(statsIterator.hasNext()){
  i++;
  PerfStatBean perfBean = statsIterator.next();
  .........
}

statFilterResults.clear();
2 голосов
/ 14 июля 2009
1 голос
/ 14 июля 2009
while(statsIterator.hasNext()){
  i++;
  PerfStatBean perfBean = statsIterator.next();
  statsIterator.remove();
1 голос
/ 14 июля 2009
ListIterator<PerfStatBean> statsIterator = statFilterResults.iterator();
while(statsIterator.hasNext()){
  i++;
  PerfStatBean perfBean = statsIterator.next();
  ...
  statsIterator.remove();
}
1 голос
/ 14 июля 2009

Создайте набор перед циклом, затем добавьте любые элементы, которые нужно удалить, в этот набор. После цикла позвоните

statFilterResults.removeAll(beansToDelete);

Кроме того, и, кстати, я считаю, что в целом проще - более читабельно, более легко обслуживать и т. Д. - использовать цикл foreach вместо итератора. В вашем случае это будет выглядеть примерно так:

for (PerfStatBean bean : statFilterResults) {
    ...
}
0 голосов
/ 14 июля 2009

... Я хотел бы удалить компонент из statFilterResults после того, как я пробегу его внутри цикла while, чтобы освободить память.

Если есть другая ссылка на объект вне массива, установка его на ноль не будет иметь никакого значения, память для этого объекта используется только один раз, а в Java вы видите только ссылки (или ссылочные значения) *

Так что если у вас есть что-то вроде:

this.bean = new PerfStatBean();

....

arrayList.add( this.bean );

Удаление его из списка не будет иметь никакого значения, потому что исходная ссылка все еще существует и не получит gc'ed.

Если у вас нет других ссылок за пределами коллекции, т. Е.

 arrayList.add( new PerfStatBean() );

Тогда этого должно быть достаточно:

while(....){
    .... 
}

arrayList.clear();

Потому что это удалит ссылки на объект и сделает их подходящими для gc.

Более того: если вы хотите «помочь» уменьшить количество ссылок на объект, вызывайте:

while(....){
    .... 
}

arrayList.clear();

должно быть достаточно.

0 голосов
/ 14 июля 2009

В Java вам не нужно беспокоиться об удалении объектов. Если в следующий раз при запуске сборщика мусора не будет ссылок на объект, он будет удален (GC запускается, когда есть свободные циклы процессора). Если вы хотите убедиться, что объект удален напрямую, используйте Runtime.getRuntime (). Gc ()

...