[java] 객체 참조를 잘못 사용함으로써 발생하는 메모리 누수 예시는 어떤 것들이 있나요?

객체 참조를 잘못 사용함으로써 발생하는 메모리 누수는 다양한 형태로 나타날 수 있습니다. 여기에 몇 가지 예시를 들어보겠습니다:

  1. 정적 컬렉션에 객체를 계속해서 추가하는 경우: 정적 컬렉션은 애플리케이션 전체에서 공유되기 때문에, 객체를 정적 컬렉션에 추가한 후에도 그 객체를 사용하지 않는다면 메모리에 계속 남아있을 수 있습니다.

예시:

public class MemoryLeakExample {
    private static List<Object> myList = new ArrayList<>();

    public static void addObject(Object obj) {
        myList.add(obj);
    }

    public static void main(String[] args) {
        Object obj = new Object();
        addObject(obj);
        // obj 는 더 이상 사용되지 않지만 myList 에서 참조가 유지된다.
        // 따라서 obj 가 메모리에서 해제되지 않고 남게됨.
    }
}
  1. 익명 클래스 사용: 익명 클래스를 사용하여 객체를 생성할 때, 해당 익명 클래스의 인스턴스가 외부 클래스의 인스턴스를 참조하게 되면, 익명 클래스의 인스턴스가 계속해서 사용되지 않더라도 외부 클래스의 인스턴스가 메모리에 유지될 수 있습니다.

예시:

public class MemoryLeakExample {
    private ActionListener listener;

    public void setListener(ActionListener listener) {
        this.listener = listener;
    }

    public static void main(String[] args) {
        MemoryLeakExample example = new MemoryLeakExample();
        example.setListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Action performed.");
            }
        });
        // listener 는 더 이상 사용되지 않지만 익명 클래스의 인스턴스가 example 에서 계속해서 유지됨.
        // 따라서 example 인스턴스가 메모리에서 해제되지 않고 남게됨.
    }
}
  1. WeakHashMap 사용 시 키로 사용되는 객체의 참조가 유지되지 않는 경우: WeakHashMap은 사용되지 않는 키가 자동으로 제거되는 맵이지만, 키로 사용되는 객체의 참조가 계속해서 유지되어야만 해당 키가 자동으로 제거될 수 있습니다. 따라서 키의 참조가 제대로 관리되지 않는다면 메모리 누수가 발생할 수 있습니다.

예시:

public class MemoryLeakExample {
    private static Map<Object, Object> myMap = new WeakHashMap<>();

    public static void addObject(Object key, Object value) {
        myMap.put(key, value);
    }

    public static void main(String[] args) {
        Object objKey = new Object();  // 키 객체
        Object objValue = new Object();  // 값 객체
        addObject(objKey, objValue);
        // objKey 의 참조가 유지되지 않으면 WeakHashMap 에서 자동으로 제거되어야 하지만,
        // 여기서는 objKey 의 참조가 유지되므로 메모리에서 해제되지 않고 남게됨.
    }
}

이러한 예시들은 메모리 누수를 일으킬 수 있는 상황을 보여주고 있습니다. 따라서 개발자는 객체 참조를 사용할 때에 신중하게 관리해야 함을 인식해야 합니다.