Может ли использование слишком большого количества статических переменных вызвать утечку памяти в Java? - PullRequest
46 голосов
/ 13 марта 2009

Если в моем приложении слишком много статических переменных или методов, то по определению они будут храниться в куче. Пожалуйста, поправьте меня, если я ошибаюсь

1) Будут ли эти переменные находиться в куче, пока приложение не будет закрыто?
2) Будут ли они доступны для GC в любое время? Если нет, могу ли я сказать, что это утечка памяти?

Ответы [ 5 ]

83 голосов
/ 13 марта 2009

Статические методы - это просто методы, они не хранятся в куче, они просто не могут использовать параметр "this".

Статические переменные служат «корнями» для ГХ. В результате, если вы явно не установите для них значение null, они будут жить столько, сколько длится программа, и поэтому все, что можно с ними сделать, доступно.

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

Что касается вашего вопроса о куче: все объекты в Java существуют либо в куче, либо в стеке. Объекты создаются в куче с новым оператором. Ссылка затем прилагается к ним. Если ссылка становится нулевой или выходит из области видимости (например, конец блока), GC понимает, что нет никакого способа достичь этого объекта когда-либо снова, и восстанавливает его. Если ваша ссылка находится в статической переменной, она никогда не выпадает из области видимости, но вы все равно можете установить для нее значение null или другой объект.

3 голосов
/ 19 марта 2009

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

2 голосов
/ 13 марта 2009

Объекты, на которые прямо или косвенно ссылается статика, будут оставаться в куче до тех пор, пока не будет собран соответствующий загрузчик классов. В некоторых случаях (например, ThreadLocal) другие объекты косвенно ссылаются на загрузчик классов, в результате чего он остается несобранным.

Если у вас есть, скажем, статический список List, и вы динамически добавляете ссылки на него, то вы можете очень легко получить «проблемы с конфликтом времени жизни объекта». Избегайте изменчивой статики по многим причинам.

1 голос
/ 13 марта 2009

Это не вызовет утечку памяти в классическом смысле C ... Например,

Class A{

static B foo;

...

static void makeFoo(){
   foo = new B();
   foo = new B();
}

В этом случае вызов makeFoo () не приведет к утечке памяти, так как первый экземпляр может быть собран мусором.

1 голос
/ 13 марта 2009

Пока вы можете ссылаться на эти переменные откуда-то в коде, это не может быть выполнено GCed, что означает, что они будут там до конца приложения.

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

...