2012-07-20 5 views
0

I 클래스가 있습니다스레드 영원히

class RenderView implements Runnable { 
    Thread renderThread; 
    public void run() { 
     while(!Thread.currentThread().isInterrupted()) { 
      //does some work 
     } 
} 

//At some point in executed code, inside RenderView class (i'm sure it's executed) 
renderThread = new Thread (this); 

//When activity is closed (also, i'm sure this part is executed) 
renderThread.interrupt(); 

가 그리고 renderThread 정말 중지를 (적어도, 실행() 메소드는 종료됩니다).

하지만 어떤 이유로 든 내 활동을 종료 한 후 내 코드에 renderView에 대한 참조가 남아 있습니다. 이로 인해 엄청난 메모리 누수가 발생합니다.

그리고 HPROF 덤프는 나에게 말한다 : java.lang.Thread의 (이 하나가 GC의 루트에) 가 대상에 대한 참조 (mypackage.RenderView)

나는 아무 생각을 가지고 왜 Thread 클래스 이미 스레드를 완료 했음에도 불구하고 내 스레드에 대한 참조를 유지합니다! 아이디어가 있으십니까?

EDIT : renderView는 Activity B에서 참조됩니다. 따라서 액티비티를 종료하면 renderThread에 대한 참조가 계속 도달 할 수 있습니다. 하지만 여전히 renderThread 설정 null = null : 작동하지 않습니다. 내가 MAT Analyzer를 통해 알 수 있듯이, 은 renderView를 가비지 수집에서 유지하는 유일한 것이 java.lang.Thread의 위어 참조입니다.

MAT Analyzer Screenshot

+0

안드로이드 솔루션은 스레드를 관리하지 않습니다. runOnUIThread에서 AsyncTask를 사용하면 대부분의 작업에서 작동합니다. –

+0

그러나 이들이 작동하지 않는 특별한 경우를 발견했다면 자세히 설명하십시오. –

답변

2

은 왜 그냥 AsyncTask를 또는 runOnUIThread를 사용하지 않는()?

나는 당신이하는 일에 대한 필요성을 결코 보지 못했습니다. 어쩌면 하나 있지만 다른 AsyncTask 또는 runOnUIThread 사용하십시오. 바퀴를 재발 명하지 마십시오.

+0

나는 바퀴를 재발 명하고 있었다는 것을 몰랐다. 나는이 기능을 살펴볼 것이다. 고맙습니다. –

+0

runOnUIThread는 잘 알려져 있지 않습니다. 이 또는 AsyncTask가 작동하는 경우 질문에 답변으로 표시하십시오. 감사합니다. –

+0

질문에 약간의 차이가 있습니다. Lunar Lander와 같은 예제에서 쓰레드를 사용하는 것을 보았습니다. SDK 2.3과 함께 제공되는 샘플입니다. 제안을 사용하여 코드를 다시 구현하려면 잠시 시간이 걸릴 것입니다. 나는 일시적으로 메모리 누출을 줄이려고 노력했다. 도움을 주셔서 대단히 감사합니다. 제안을 사용하여 코드를 다시 구현할 때 메모리 누수가 해결되면 올바른 답으로 표시 할 것입니다. 지금 당장 표시 할 수 있을지 모르겠다. 하지만 대답 해줘서 고마워. –

0

renderThread을 무효화하려고 시도 했습니까?

+0

예. 이 새로운 정보를 EDIT에 포함 시켰습니다. –

1

은 스레드 인스턴스가 다른 인스턴스로입니다

renderThread = null; 

, 객체와 스레드 인스턴스를 해제합니다. 실행이 완료 되더라도 릴리스 할 때까지 참조를 유지합니다.

+0

문제는, 어쨌든 renderThread가 포함 된 renderView가 포함 된 활동에 대한 참조가 손실되었지만 여전히 이상한 참조가 유지된다는 것입니다. 편집을 참조하십시오. 나는 어쨌든 무효화를 시도했지만 결코 알지 못합니다. –

0

실제로 renderThread.interrupt는 스레드를 멈추지 않을 수 있습니다. 플래그를 설정하고 JVM을 중단시킬 수 있습니다. 이것이 스레드가 여전히 실행 중일 수 있습니다. 최상의 방법은 정상적으로 run 메소드를 종료하는 것입니다. while 루프에서 플래그를 설정하면됩니다.

while(isRunning){ 

    } 

// at some point, say 

    isRunning = false; 

Android UI 디자인에 대한 우수 사례는 다음 링크에서 얻을 수 있습니다.

Android UI design pattern:

+0

아, 그냥 내 코드에서 볼 수 있듯이이 플래그와 같은 방식으로 인터럽트를 사용합니다. 나는 잠깐 (! Thread.currentThread(). isInterrupted())을 수행한다. renderThread.interrupt()를 호출하면 스레드가 종료됩니다 (실제로 테스트 한 후 코드가 실제로 도달했습니다). –

+0

@ userEng15,이 작업을 통해 루프 밖으로 빠져 나올 수는 있지만 스레드가 멈추지 않습니다. 이것이 프로파일 작성자에서 볼 수있는 이유입니다. – UVM

+0

renderThread.getState()는 "TERMINATED"를 표시합니다. run()이 이스케이프 처리되면 어떻게 멈출 수 없습니까? 나는 그것을 멈추는 정의로 삼았다. –