Thread 객체에서 run()을 호출하면 Java 프로그램에서 메모리 누수가 발생하는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/107823

문제

(위험 스타일 질문입니다. 이 문제가 발생했을 때 답변이 온라인에 있었더라면 좋았을 것입니다.)

Java 1.4를 사용하면 가끔 스레드로 실행하고 싶지만 다른 경우에는 실행하지 않으려는 메서드가 있습니다.그래서 나는 이것을 Thread의 하위 클래스로 선언한 다음 필요한 것에 따라 start() 또는 run()을 호출했습니다.

하지만 내 프로그램이 시간이 지남에 따라 메모리 누수를 겪는다는 사실을 발견했습니다.내가 도대체 ​​뭘 잘못하고있는 겁니까?

도움이 되었습니까?

해결책

이것은 Java 1.4의 알려진 버그입니다.http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=5869e03fee226ffffffffc40d4fa881a86e3:WuuT?bug_id=4533087

이는 Java 1.5에서 수정되었지만 Sun은 1.4에서 이를 수정할 계획이 없습니다.

문제는 공사기간 중 Thread 내부 스레드 테이블의 참조 목록에 추가됩니다.start() 메소드가 완료될 때까지 해당 목록에서 제거되지 않습니다.해당 참조가 있는 한 가비지 수집되지 않습니다.

따라서 확실히 호출하지 않는 한 스레드를 생성하지 마십시오. start() 방법.ㅏ Thread 사물 run() 메소드를 직접 호출하면 안 됩니다.

코딩하는 더 좋은 방법은 다음을 구현하는 것입니다. Runnable 하위 클래스가 아닌 인터페이스 Thread.스레드가 필요하지 않으면 전화하십시오.

myRunnable.run();

스레드가 필요한 경우:

Thread myThread = new Thread(myRunnable);
myThread.start();

다른 팁

Thread 인스턴스나 그 하위 클래스를 구성하면 메모리가 누출될지 의심스럽습니다.첫째, Javadocs나 Java 언어 사양에 언급된 종류의 내용은 없습니다.둘째, 간단한 테스트를 실행했는데 메모리가 누출되지 않는 것으로 나타났습니다(적어도 32비트 x86 Linux 2.6의 Sun JDK 1.5.0_05에서는 누출되지 않음).

public final class Test {
  public static final void main(String[] params) throws Exception {
    final Runtime rt = Runtime.getRuntime();
    long i = 0;
    while(true) {
      new MyThread().run();
      i++;
      if ((i % 100) == 0) {
        System.out.println((i / 100) + ": " + (rt.freeMemory() / 1024 / 1024) + " " + (rt.totalMemory() / 1024 / 1024));
      }
    }
  }

  static class MyThread extends Thread {
    private final byte[] tmp = new byte[10 * 1024 * 1024];

    public void run() {
      System.out.print(".");
    }
  }
}

편집하다:위 테스트의 아이디어를 요약해 보겠습니다.Thread의 MyThread 하위 클래스의 모든 인스턴스는 자체 10MB 배열을 참조합니다.MyThread의 인스턴스가 가비지 수집되지 않으면 JVM의 메모리가 매우 빨리 부족해집니다.그러나 테스트 코드를 실행하면 JVM이 지금까지 구성된 MyThreads 수에 관계없이 소량의 일정한 양의 메모리를 사용하고 있음을 알 수 있습니다.나는 이것이 MyThread의 인스턴스가 가비지 수집되기 때문이라고 주장합니다.

문제의 핵심에 더 가까이 다가갈 수 있는지 살펴보겠습니다.

스레드에서 start()를 사용하여 1000x, run()을 사용하여 1000x로 프로그램을 시작하면 둘 다 메모리가 느슨합니까?그렇다면 알고리즘을 확인해야 합니다(예:Runnable에 사용되는 벡터와 같은 외부 객체의 경우).

위에서 설명한 대로 메모리 누수가 발생하지 않으면 JVM과 관련된 스레드의 시작 매개변수 및 메모리 사용량을 조사해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top