2009-07-14 4 views
1

내 개발자와 저는 우리가 원하지 않는 응용 프로그램에서 객체를 가비지 수집하는 데 문제가 있습니다. 우리는 Weblogic 10g3에서 Java를 사용하고 있습니다. 모든 JMS 연결을 처리하기 위해 싱글 톤 패턴을 프로그래밍하고 있습니다.왜 쓰레기 수거 되나요?

관련된 두 개의 클래스가 있습니다

public class JMSObject { 
... 
private MessageProducer _producer; 
private MessageConsumer _consumer; 
... 
// standard get/set procs... etc. 
} 

public class JMSFactory { 
... 
// Hashmap sessions with key == ConnectionFactory Name 
    Hashmap<String, List<Session>> _sessions; 

// Hashmap of JMSObjects with key == ConnectionFactory Name + JMS Queue Name 
    Hashmap<String, List<JMSObject>> _jmsobjects; 
... 
// standard get/set & necessary sington functions 
} 

서블릿의 초기화 방법은 JMSFactory의 singlton 메소드를 호출, 새로운 세션이 JMSObject로 생성 된 _sessions 해시 맵과 새로운 MessageConsumer/MessageProducers에 배치하고 배치가 _jmsobjects 해시 맵의 해당 목록에 있습니다.

문제는 시스템이 실행 중일 때 목록의 JMSObject가 일정 시간 후 가비지 수집을 받는다는 것입니다 (때로는 몇 시간 후 다른 시간에 5 분이 소요됨). 며칠 동안 이것을 보았지만 아무 것도 찾을 수 없었습니다 JMSObject가 수집 된 garbarge의 이유. JMSFactory가 그들에 대한 참조를 가지고 있기 때문에 왜 Gc가 그들을 파괴 할까? 우리는 다음과 같이 등급을 변경하여 고정 결국

(방법 인터페이스를 변경하지 않고)

public class JMSObject { 
... 
private List<MessageProducer> _producers; 
private List<MessageConsumer> _consumers; 
... 
// standard get/set procs... etc. 
} 

public class JMSFactory { 
... 
// Hashmap sessions with key == ConnectionFactory Name 
    Hashmap<String, List<Session>> _sessions; 

// Hashmap of JMSObjects with key == ConnectionFactory Name + JMS Queue Name 
    private Hashmap<String JMSObject> _jmsobjects; 
... 
// standard get/set & necessary sington functions 
} 

지금까지 JMSObjects을 테스트 gc'ed가되는 것은 아니다. 그것은 2 일 동안 계속 달리고있다.

간접 참조로 인해 JMSObject가 gc'ed가되는 이유를 설명 할 수 있습니까? 그리고 왜 세션 해시 맵에서 세션을 얻지 못했을까요? 세션이 Javax 형식으로 작성되었으며 JMSObject는 우리가 작성한 것과 관련이 있습니까?

+0

'JMSObject'가 가비지 수집을 할 때 목록의 크기를 그대로 유지하지만 시도 할 때'null'이 표시됩니까? –

+0

@Jack Leow, Yes NullPointerException ... :-(( – beggs

답변

2

나는 당신의 문제가 무엇인지 알고 있다고 생각하는데, 그것은 잠시 후에 (WebLogic 6에서) 실행 한 것입니다. 나는 WebLogic이 동적 인 클래스를 다시로드하는 것과 관련이 있다고 생각한다. WebLogic은 개발 환경에 있지 않은 경우에도 때때로 WebLogic이하는 것처럼 보인다. (나는 web.xml이 어떻게 든 어떤 서비스 나 뭔가에 의해 영향을 받고 있다고 생각한다.).

우리의 경우에는 어떤 클래스의 정적 변수로 정의 된 객체의 단일 인스턴스가 있으며, 사용자와 마찬가지로 시작시로드가있는 서블릿에 의해 초기화됩니다 매개 변수 집합. WebLogic은 변경 사항이 있다고 판단 할 때 클래스 로더를 garbage collection ()으로 다시로드하지만은 "load-on-startup"으로 표시된 모든 서블릿을 다시 초기화하지 않습니다. 나는 서블릿이 정적 변수를 초기화하는 것 외에 다른 용도로 사용되지 않는다. 정적 변수를 매핑 할 필요가 없으므로 호출 할 수 없다. 정적 변수는 GCed가되지만 다시 초기화되지는 않는다. 서버가 있어야한다.

우리의 솔루션은 정적 초기화 프로그램에서 정적 변수를 초기화하는 것이 었습니다. 원래 개발자는 실제로 필요하지 않은 서블릿 컨텍스트 정보를 원했기 때문에 서블릿을 사용하여 변수를 초기화했습니다. 컨텍스트 정보가 필요하면 초기화를 ServletContextListener에 시도해 볼 수 있습니다.

+0

@ Jack Leow; 흥미로운 점은 Dynamic Class Reloading의 동작을 조사해야한다는 것입니다. 네가 말하는 것처럼 말하는 것 같아. 공평하지 않아. 우리는 새로운 구현 (두 번째 코드 블록)에서 문제를 보지 않고 있지만 근본 원인을 파악해야합니다. 감사. – beggs

+1

나는 그것을 보았다. 그리고 그것이 내가 더 빨리 반응하지 않은 이유 중 하나이다. 즉 며칠 동안 만 안정화되었다고 말했습니까?이 경우 시스템이 문제를 일으키기 전에 수 주일 동안 시스템이 작동하는 경우가 있습니다. –

+0

두 번째 버전에서 문제가 발생하기 시작 했으므로 받아 들였습니까? :) –

5

JMSFactory에는 이들에 대한 참조가 있기 때문에 왜 gc가이를 파괴합니까?

이 시점에서 여전히 JMSFactory에 대한 참조를 보유하고있는 객체가 있습니까?

public class Singleton { 
    private static Singleton instance = new Singleton(); 

    private Singleton() { 
     //constructor... 
    } 

    public static Singleton getInstance() { return instance; } 
} 

이 당신은 다음과 같습니다 패턴이 없습니다 :

일반적인 싱글 톤 패턴은 정적 멤버에서 단일 객체에 대한 참조를 유지? 실제 싱글 톤 코드를 생략하면 실제 싱글 톤 코드를 생략 했으므로 게시물에서 제공 한 코드에서 알 수 없습니다. ...

(이 경우와 같은 것으로 Singletons를 사용하면 통증을 유발할 수 있습니다. 테스트. Singletons Are Pathlogical Liars을 참조하십시오.

+0

@matt b ... 그렇습니다. 정적, 약간 다른 코드입니다 (우리는 생성자에서 싱글 톤을 인스턴스화하지만 변수는 정적입니다). 흥미로운 기사, 링크입니다. – beggs

+0

게시하는 코드가 실제로 문제가있는 코드가 아닌 경우 문제를 해결하는 데 약간의 어려움이 있습니다 ... –

+0

상업 코드를 게시 할 수 없습니다. ;-)가 위반합니다. 기업 규칙. – beggs

0

_sessions 맵의 세션은 GC가 아니지만 JMSObject는 그렇지 않다고 말했습니까? 나는 그것이 당신이 쓴 것이기 때문에 그것이 의심 스럽습니다. JMSFactory 자체가 수집되고 있거나 (예 : 제대로 구현되지 않은 싱글 톤) 또는 맵에서 키를 제거하는 것으로 들리는 것 같습니다. 두 경우 모두, JMSObjects는 GC를 사용할 수 있지만 목록에 여전히 참조가 있으므로 세션 객체는 그렇지 않습니다.

1

어려운 코드를 모두 풀지 않고도 해결할 수 있습니다. 그러나 도움이되는 도구가 있습니다.

다음 링크를 사용해보십시오 : http://blog.emptyway.com/2007/04/02/finding-memory-leaks-in-java-apps/ jhat 및 jmap 사용에 대한 정보를 제공합니다. 이 기사는 메모리 누수를 찾기 위해 작성되었지만 객체에 대한 참조를 추적하는 방법에 대한 정보를 제공합니다. 어쩌면 참조가 사라지는 이유를 추적 할 수 있습니다.

0

JMSFactory를로드 한 클래스 로더가 언로드되어 JMSFactory 클래스를 GC'ed (싱글 톤 인스턴스 포함)로 만들면 HashMaps와 그 내용을 비울 수 있습니까?

관련 문제