Создание утечки памяти с Java
У меня только что было интервью, и меня попросили создать утечку памяти с помощью Java. Излишне говорить, что я чувствовал себя довольно глупо, не имея ни малейшего понятия о том, как его начать.
Каким будет пример?
63 ответа
Из эффективной книги Java
- всякий раз, когда класс управляет собственной памятью, программист должен быть готов к утечкам памяти
,
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly doubling the capacity
* each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
Можете ли вы обнаружить утечку памяти? Так где же утечка памяти? Если стек увеличивается, а затем сжимается, объекты, извлеченные из стека, не будут собираться мусором, даже если у программы, использующей этот стек, больше нет ссылок на них. Это потому, что стек поддерживает устаревшие ссылки на эти объекты. Устаревшая ссылка - это просто ссылка, которая никогда не будет разыменована. В этом случае любые ссылки вне "активной части" массива элементов являются устаревшими. Активная часть состоит из элементов, индекс которых меньше размера.
В Java нет такой вещи, как утечка памяти. Утечка памяти - это фраза, заимствованная у C et al. Java имеет дело с распределением памяти внутри с помощью GC. Это бесполезная трата памяти (то есть, оставление неактивных объектов), но не утечка памяти.
Вот очень простая Java-программа, в которой не хватает места
public class OutOfMemory {
public static void main(String[] arg) {
List<Long> mem = new LinkedList<Long>();
while (true) {
mem.add(new Long(Long.MAX_VALUE));
}
}
}