Переменные Java -> заменить? Оптимизация оперативной памяти - PullRequest
2 голосов
/ 10 мая 2010

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

Что происходит в моей оперативной памяти, когда я говорю, например, это:

ArrayList<String> al = new ArrayList<String>();
...add values, work with it and so on....

al = new ArrayList<String>();

Так мой первый ArrayList хранится в ОЗУ или второй ArrayList будет храниться в той же позиции, где был первый? Или это просто изменит ссылку "al"?

Если он не заменен ... есть ли способ вручную освободить оперативную память, которая была занята первым массивом? (не дожидаясь сборщика мусора) Поможет ли это установить сначала = null?

Хороший привет, poeschlorn

Ответы [ 3 ]

4 голосов
/ 10 мая 2010

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

Установка переменных на нуль не имеет значения, когда для нее задано что-то другое сразу после этого, или это локальная переменная, которая в любом случае скоро выйдет из области видимости (но внутри структур данных, таких как ArrayList, установка элементов содержимого массива на ноль, когда элемент удален, требуется во избежание утечек памяти).

4 голосов
/ 10 мая 2010

Код, который вы публикуете, выделит новый экземпляр ArrayList. Если вы хотите использовать один и тот же, вы можете сделать это:

ArrayList<String> al = new ArrayList<String>();
...add values, work with it and so on....

al.clear();
// now you can use a1

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

Но также обратите внимание, что экономия, которую вы получаете от переработки массивов объектов и списков массивов, не так уж велика. Если в ArrayList вы храните строки размером 10 x 4096 байт, сам список массивов занимает только пространство, пропорциональное размеру ссылок, например, около 4 байтов х 10 = 40 байтов. Это упрощение, но принцип верен. Таким образом, даже если вы повторно используете тот же список массивов, вы экономите только память, используемую для хранения ссылок на объекты, а не сами объекты. Имея это в виду и риск возникновения ошибок из-за непреднамеренного изменения коллекции, я бы предположил, что большинство людей не беспокоятся об утилизации списков.

Управление памятью в современной виртуальной машине действительно очень хорошо, и вам следует начинать «оптимизацию» памяти только тогда, когда вы видите, что в этом есть необходимость. Фактически, использование объектов дольше, чем их естественное время жизни, может отрицательно повлиять на производительность сборки мусора.

Мой совет: сначала четко кодируйте, профилируйте и сосредоточьтесь на оптимизации использования памяти только тогда, когда вы видите, что есть проблема и определили причину.

Удачи!

1 голос
/ 10 мая 2010

Новое пространство в куче будет выделено для нового ArrayList.

Вы не можете форсировать сборку мусора, и присвоение нулевого значения будет служить только для загрузки процессорных циклов. Вы можете позвонить System.gc(), чтобы предложить JVM запустить сборщик мусора, но нет никаких гарантий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...