달력

122024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

리소스 누수현상

java 2006. 2. 21. 10:07

http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=consult&c=r_p&n=1106886851

제목 : 긴급! 리소스 누수 현상 ㅜ.ㅜ
글쓴이: 김영근(naucika) 2005/01/28 13:34:11 조회수:7258 줄수:41
안녕하세요. 
이번에 사내 SFA 서비스가 말썽이 생겨서 도움을 좀 부탁드립니다.
프로젝트가 끝난지는 2년이 다 되가는데요.
이번에 자주 웹서버가 다운되는 바람에 애를 먹고 있습니다.
도대체 원인을 모르겠고, 뭘 더 어떻게 해야할지 모르겠네요.

환경을 말씀드리면,
JBOSS 3.2.5 구요. 서버는 제온 프로세서 2, 메모리 1G 정도입니다. 윈도2003 서버구요.
두개의 서비스가 구동중인데요.
하나는 SFA(영업관리 시스템), 또 하나는 채용시스템입니다.

SFA는 초기모델이라 자체 프레임웍에 서블릿 JSP로 구성되어 있고, JBOSS에서 제공하고 
있는 DB POOL을 사용합니다.
채용시스템은 하이버네이트+스트럿츠+서블릿+JSP+스프링 프레임웍등으로 
구성되어 있구요 하이버네이트에 플러그인인 proxool 을 설정해서 쓰고 있습니다.
둘다 최소 10개 최대 30개 정도의 커넥션 풀로 구성되게 해놓았구요.

사용자층은 SFA는 사내 영업직원 약 300명 가량 동시접속자 2~30명정도구요.
채용은 몰릴때 일시적으로 몰리는데요 하루 400명정도 가량 접속을 합니다.

일단 로그를 확인해보면, 
어쩔땐 OutOfMemory 로 완전히 엔진이 맛이 간적도 있구요.
connection time out으로 pool에서 커넥션을 제대로 못가져오는 경우도 있구요.
getOutputStream() has already been called for this response -> 이에러도 많이 발생합니다.
정말 궁금한거 위에러는 열린거 또 열려고 할때 발생하는것 같은데,
이건 도대체 감을 잡을수가 없습니다. 

소스도 디테일하게 체크해봤지만, 에러가 발생한다고 해서 커넥션 반납에 문제가 있을
만한 내용은 없었습니다. finally 혹은 외부에서 exception을 처리해서 최대한 신경을
썻는데요.. 스트레스 테스트는 고사하고, 모니터링이라도 제대로 해보고 싶은데
튜닝쪽 정보나 실력이 영 모자랍니다.

일단, 전문가가 계시면 비용문제를 떠나서 좀 와서 봐주셨으면 좋겠구요.
아니면 이런 튜닝쪽을 의뢰할 방법이나 연락처라도 알려주시면 좋겠구요.
그것도 아니면, 힌트라도.. ㅜ.ㅜ 위에서 난리가 나서, 정말 갑갑합니다.
도와주세요~



온세상을 자바로~ -_-!!
http://cafe.naver.com/javalove
제목 : Re: 메모리 누수현상 원인 분석 방법
글쓴이: 이원영(javaservice) 2005/01/29 14:44:23 조회수:3042 줄수:53
언급하신 증상은 조금더 면밀한 조사가 필요하나 대부분 다음과 같은 원인에 의해 발생할
수 있습니다.

1) Statement/PreparedStatement/ResultSet을 정상적으로 닫지 않을 경우, native memory
 leak의 주원인이 되어, (JVM Heap메모리와 무관하게), OutOfMemoryError를 유발하게
 됩니다. 이 경우, 아래의 문서에 기술된 바와 같이 JDBC 코딩 가이드라인을 준수하지
 않은 것이 원인이라, 해당 어플리케이션을 수정하셔야만 해결이 됩니다.

 서블렛 + JDBC 연동시 코딩 고려사항 -제1탄- 
 http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=servlet&c=r_p&n=968185187

 문제는 어떤 어플리케이션에서 그러한 문제를 유발하고 있느냐를 찾기가 운영단계에서는
 쉽지가 않은데, 아래와 같은 실시간 모니터링 툴을 설치하시면 매우 쉽게 찾아집니다.


2) native memory가 아닌 Heap memory 가 정말 부족하게 설정되어 있을 수 있습니다.
 heap memory는 -Xms -Xmx로 설정가능하며, heap memory는 Runtime의 freeMemory()
 totalMemory()를 이용하여 추출가능합니다. 이 또한 위의 모니터링 툴을 통해 보다
 직관적인 실시간 그래프로 모니터링이 가능합니다.

 이 경우는, 극히 정상적으로 어플리케이션이 그렇게 많은 메모리를 사용하고 있는
 구조일 수 있고, 이 경우라면 -Xms -Xmx를 통해 시스템 전체 메모리를 고려하여 충분히
 잡아주는 것과, 혹은 그러한 어플리케이션을 보다 적게 메모리를 사용하는 구조로
 변경하는 것과 같은 노력이 필요합니다.

 혹은 ObjectOutputStream의 재사용과정에서 reset()를 주지 않았다거나,

 TCP/IP Socket ObjectOutputStream.reset() 
 http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=javatip&c=r_p&n=1058887057

 혹은 WAS의 bug에 기인한 heap memory leak이라거나, 혹은 어플리케이션에서 global
 변수인 vector나 hashtable에 지속적으로 저장하는 구조이거나, 어플리케이션 레벨에서의
 cache를 구현하는 과정에서 지속적으로 메모리를 점유하는 등의 원인이 있을 수 있습니다.

 heap memory leak의 추적은 크게 두가지 방법으로 나뉩니다.
 하나는 전용 JVM Profiling Tool을 통해 JVM Heap 메모리 누수를 찾아낸다거나,
 (HP-UX의 Enterprise Edtion의 OS전용분석기, Borland OptimizeIt 등),
 두번째는 OS가 만약 IBM의 AIX이거나 Windows,linux라면 IBM JDK의 자체기능인 heapdump를
 이용하여 이를 HeapRoot라는 툴로 분석하여 매우 쉽게 어떤 객체 어느 곳에서
 memory leak이 일어난지를 어렵지 않은 방법으로 찾아낼 수 있습니다.

 IBM HeapDump & HeapRoots
 http://www.javaservice.net/~java/bbs/read.cgi?m=dbms&b=jdbc&c=r_p&n=1083294657

결론적으로, 우선 Jennifer 전체적인 상황을 보다 면밀히 판단하고, memory leak의
형태에 따라 적절히 그 원인을 추적해 들어가시면 되겠습니다.


자바서비스컨설팅 이원영
e-mail : lwy@javaservice.com
MSN : javaservice@hanmail.net
Phone: 010-6239-6498
제목 : Re: 기본적인 것 부터 확인해 보세요.
글쓴이: 박철휘(guest) 2005/01/30 17:39:34 조회수:1452 줄수:58
이원영씨께서 답해주신 것이 옳은 방법이나 일단 문제가 생긴 시점에서 profilling 기법도
모르는데 그러한 정보로 해결을 한다는 것은 매우 어려운 일인 것 같습니다.

말씀하신대로 전문가의 도움을 받으시는 것이 비용대비 효율상 가장 좋을 것 같습니다.

다만 여의치 않으시다면 일반적인 요령 몇가지가 있습니다.
제 경험으론 이런게 사실 문제의 원인인 경우가 대부분이더군요.
그리고 그래도 안된다면 해결하는데 시간 많이 들어갑니다.

1. 웹서버 다운
서버자체가 먹통이 된다면 서버를 바꾸는 것이 좋을 것입니다.
OS와 하드웨어의 궁합으로 인한 문제가 간혹 있습니다. 
이것은 자바만의 문제가 아닌 모든 application에 해당되며 재수가 없는 것입니다.

application이 다운되는데 OOM(OutOfMemory)라면 십중팔구는 heap memory가 full 이 난
것입니다. 메모리 누수요인을 체크하는 것이 좋은데 이원영씨께서 말씀하신 부분이 원인인
경우가 대부분입니다. 그것이 요인이 아니라면 찾는 것이 어렵지는 않으나 시간이 꽤 걸립니다.
무엇을 실행시켰는데 heap에 메모리를 반환하지 않는지 일일히 확인해봐야 합니다.
Optimizeit으로 찾으려면 수작업이 조금 들어가구요. ServerTrace를 사용하면 매우 직관적이고
편리하게 이 문제를 확인할 수 있습니다.

application이 다운된 것은 아닌데 하얀화면만 나오는 이른바 hang 현상이라면 dead lock인
경우가 많고 간혹 WAS와 JVM의 bug로 인한 것이 있습니다.
이런건 지속적인 dump나 hang이 걸리는 시점에서 몇번의 dump 만으로도 문제의 원인을 찾을
수 있습니다. OOM보다 오히려 문제의 원인을 찾는데 시간이 적게 들어가는 경우가 많습니다.

2. POOL에서의 Connection Time Out
WAS가 허용하는 Connection 갯수 대비 connection pool 갯수가 현저히 적을 경우 발생하는
경우가 많습니다. connection pool 갯수를 늘리든지 WAS의 connection 갯수를 줄이든지 해서
경과를 지켜보시는게 좋을겁니다. 그렇지 않다면 db에서 허용하는 max connection num을
확인해 보세요.

3. getOutputStream()
외부 프레임워크를 쓰는데 이런 일이 발생하는 경우라면 ServletResponse를 직접 제어하는데
제대로 못써서 그런 경우이거나 프레임워크 자체를 잘 못 써서 그런 경우가 많습니다.
보통 파일 다운로드나 redirect를 해놓고 처리를 종료하는 것이 아니라 프레임워크에게 계속
처리가 넘어가는 경우 많이 생깁니다.

4. 하이버네이트+스트럿츠+서블릿+JSP+스프링 프레임웍
요즘 외국에서 인기리에 사용되는 방식인데 이것을 모두 도입하여 사용하실 정도인데 위의
문제가 발생하는 것이 조금 의문이네요.
하이버네이트 : 다 좋은데 가르치는데 시간이 많이 들더군요. 교육비용이 매우 많이 드는 것
같습니다. 이해의 부족으로 인한 결함 요인이 자꾸 생겨서 그때마다 확인해주는 것도 보통
일이 아니더군요. 그냥 포기하고 native sql을 사용하는 DAO로 전환시켰습니다.
스프링 : JBOSS를 사용하신다면 EJB를 사용하시는 것이 아닌가요. 그런데도 spring이 필요한
점이 의외네요.
스트러츠 : 이런거 쓸 때는 reponse를 직접 제어하는거 주의하시는게 좋습니다. 파일다운로드는
별도의 서블릿으로 사용하시는게 속편할 겁니다.
제 개인적인 견해로는 Hibernate를 쓰면서 spring과 결합이라면 transaction에 대한 부분이
매력이지만 critical한 것도 아닌 것이라면 없어도 무리는 없을 것 같은데요. 일반적으로
ThreadLocal을 사용하여 request당 Session 하나를 두는 것을 권장합니다. hibernate에서도
그것을 권장하는 편이구요.

이런 문제를 해결하면서 많은 것을 배우게 됩니다.
하지만 이것 때문에 내 목이 위태로운 상태라면 문제는 보통 심각한게 아니겠지요.
전문가에게 맡기는 방법이라면 프리랜서를 고용하는 방법이나 비싼 WAS 구매하면서 이 부분에
대한 분석을 요청하시면 될 겁니다. (이것도 운이 좀 필요하더군요. 이 문제를 곧바로
해결해주는 엔지니어를 만나신다면 행운입니다.)
제목 : Re: 좋은의견 주셔서 감사합니다.
글쓴이: 김영근(naucika) 2005/01/31 09:15:02 조회수:1133 줄수:28
저번주 금요일부터 나타나는 오류들을 하나하나씩 잡고, 주말에 추이를 좀 지켜보았는데요.
역시나, outofmemory가 떨어졌습니다.

로그확인결과, 
[net.sf.hibernate.collection.PersistentCollection] Failed to lazily initialize a collection
이란 하이버네이트 오류가 발생했구요. 
-> 공지사항 검색 로직인데, lazy 방식으로 로드합니다. 공지사항이 없을리는 만무하고,
특정구간에서 발생하는 오류인듯 싶습니다.

[org.jboss.web.localhost.Engine] StandardWrapperValve[jsp]: 
Servlet.service() for servlet jsp threw exception
java.lang.OutOfMemoryError
그외에 이렇게 oom 이 자주 일어나고, 종국엔 새벽경에 서버가 다운됬습니다.
한두시간정도 이런 oom이 계속 발생한거 같습니다.

철휘님이 말씀하신것중에 hibernate와 jboss 사용이유는 원래 ejb를 사용했던것인데요.
이번에 o/r mapping 으로 리뉴어링 했습니다. 굳이 서버를 변경할 필요까진 없어서
그대로 사용을 했던거구요, 이서버에 sfa(영업관리시스템)을 통합운영하게 된거죠.

그외에 퍼포먼스 가이드를 계속 살펴보고 있습니다.
로그분석도 이번주에 시작해 볼 예정입니다만, 솔직히 자신이 없네요. 
발견되는 내용은 족족 게시판에 업로드 하겠습니다..

수고하세요.


온세상을 자바로~ -_-!!
http://cafe.naver.com/javalove
제목 : Re: 하이버네이트
글쓴이: 손님(guest) 2005/02/01 14:07:32 조회수:1491 줄수:51
기억이 가물가물한데....항상 시간이 지나면 잊어버리니..쩝..
하이버네이트요...세션클로즈방식이 잘못쓰면 저런에러가 나왔던기억이...나네요..
종국에는 이원영님의 1번코멘트가 정답일겁니다.

제 가물가물한 기억으로는...1.1버전썼던것같은데 벌써3.0버전이되버렸네여..

Session session = _sessions.openSession();
        Transaction tx = null;
        List result = null;
        try {
            tx = session.beginTransaction();
            Query q = session.createQuery(
                "select blog.id, blog.name, count(blogItem) " +
                "from Blog as blog " +
                "left outer join blog.items as blogItem " +
                "group by blog.name, blog.id " +
                "order by max(blogItem.datetime)"
            );
            q.setMaxResults(max);
            result = q.list();
            tx.commit();
        }
        catch (HibernateException he) {
            if (tx!=null) tx.rollback();
            throw he;
        }
        finally {
            session.close();
        }
        return result;
    }

이와같이 준수하여 사용하셨는지 함 확인해보시기 바랍니다.

위의 메모리릭은 

1) Statement/PreparedStatement/ResultSet을 정상적으로 닫지 않을 경우, native memory
 leak의 주원인이 되어, (JVM Heap메모리와 무관하게), OutOfMemoryError를 유발하게
 됩니다. 이 경우, 아래의 문서에 기술된 바와 같이 JDBC 코딩 가이드라인을 준수하지
 않은 것이 원인이라, 해당 어플리케이션을 수정하셔야만 해결이 됩니다

요게 정답이라고 사료됩니다. 단 하이버네이트의 경우 세션이라는 개념을 사용합니다..
예전에..XX사는넘님이 이거 담당이였는데...ㅎㅎ
XX사는넘님 글보시면 코멘트부탁드립니다...케케
근데 HQL(Hibernate Query Language) 이거 제대로 쓸려니 머리좀 아프더군여..^^;





제목 : Re: 링크걸어드리져.
글쓴이: 손님(guest) 2005/02/01 14:23:53 조회수:1092 줄수:1
http://forum.hibernate.org/viewtopic.php?t=938011&highlight=failed+lazily+initialize
제목 : Re: 하이버네이트 관련글.
글쓴이: 김영근(naucika) 2005/02/01 18:16:34 조회수:1260 줄수:51
일단, 제경우 하이버네이트를 스프링 프레임웍에 붙였습니다.
코딩은 다음과 같죠.

public Object findMajorByCode(final String code, final String sc_code) throws MasterException,
			HibernateException {
	return getHibernateTemplate().execute(new HibernateCallback() {
  	      public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Criteria crit = getSession().createCriteria(HA020TB.class);
				crit.add(Expression.eq("HA02_SCHOOLCAREER_CD", sc_code));
				crit.add(Expression.eq("HA02_MAJOR_CD", code));
				List list = crit.list();
				if (list.size() > 0) {
					HA020TB data = (HA020TB) list.get(0);
					return data.getHA02_MAJOR_NM();
				} else {
					return "";
				}

			}
		});
	}

위소스처럼 되어있는데요.
세션을 직접 얻어서 쓰는경우가 거의 없습니다.
혹은 아래처럼, 

BA010TB obj = (BA010TB) getHibernateTemplate().get(BA010TB.class, zipid);

식으로, 스프링에서 제공해주는 템플릿을 애용(?)합니다.
이런, 소스내용도 잘못된걸까요?

어쨋든, 한 이틀째 모니터링을 하고 있는데요,
(하이버네이트쪽은 검사하지 않고 있습니다.) 당혹스럽게도..
stmt, rs가 안닫히는 부문이 많습니다. --;;;;
게다가, 불필요한 커넥션을 많이 가져가는 부분도 있구요. (가급적 join으로 처리할려구요)
일단, 소스는 수정하지 않은상태에서 스트레스 테스트를 해볼려구요.
과연 이렇게 안닫혀지는 stmt들이 얼마나 악영향을 끼칠지 궁금합니다.

메모리 덤프로 떠볼려구요. (서비스넷 쥔장님이 그렇게 해보는게 가장 확실하다고 해서용)
어쨋든 일단 소스는 잘못된게 확실하네요.. 
자체 프레임웍을 썻는데, 미흡했나 봅니다.

모니터링 결과는 이번주내에 나올듯 싶습니다.






온세상을 자바로~ -_-!!
http://cafe.naver.com/javalove
제목 : Re: 메모리 리익
글쓴이: 손님(dhseong)(guest) 2005/02/01 19:24:14 조회수:1063 줄수:20
1) Statement/PreparedStatement/ResultSet을 정상적으로 닫지 않을 경우, native memory
 leak의 주원인이 되어....

위와 같은 경우라면 웬만큼 커넥션을 많이 열어서 작업하지 않고서는 OutOfMemory가 
발생하기 전에 (1) DB에서 inactive size의 증가나 cursor의 증가가 먼저 확인되리라
생각됩니다.

메모리 릭 자체에 집중하시기 전에 Connection Pool관련하여 Timeout도 발생한다고
하니 DB쪽에서 어떤 증상으로 나타나는지 점검하시는게 좋을듯 합니다.

Timeout관련해서 커넥션 (2) Pool min/max를 조절하시어 증상확인도 하셔야 할듯 합니다.

그리고, (3) Heap Size를 설정하실때는 OS마다 New/Old 영역의 비율이 중요한데
Windows 계열에서는 1:11~13로 설정하는 것이 좋습니다. 
예를 들어, -XX:NewSize=64m -Xms768 -Xmx768m 으로 설정할 수 있겠지요.

Heap Size도 변경하셔서 증상 확인 다시 하실 필요가 있습니다.

저희도 하이버네이트를 사용하는 패키지를 벤더가 들고 들어와서 쓰는데, 문제생기니
골치아프더군요.
제목 : Re: 스트레스 툴 쓰는법좀 알려주시면 안될까요? --;
글쓴이: 김영근(naucika) 2005/02/02 13:08:21 조회수:1268 줄수:32
현재 Web Application Stress Tool(MS) 을 사용해 볼려고 하는데요.
각페이지를 레코딩하고, 필요없는것들은 삭제를 한후에,
돌려보는데 맨 첨 페이지만 hit수가 1번 증가하고 그이후론 깜깜무소식입니다.
왜그런건지..

host : localhost
1. get /main.jsp -> 그냥 인덱스 페이집니다.
2. post /servlet/ens.common.auth.Authmgr -> 인증관련 서블릿이구요.
   QueryString 에 id/passwd 를 넣었습니다.
3. get /market/sfa/sfainfo/afc200/cust_search.jsp -> 고객검색 화면이구요.

위에서, 웹서버쪽의 콘솔내용을 보면, 2번까지는 옵니다.
인증완료되고, redirect까지 처리합니다.
3번부터는 오지않구요. 3번이후 대략 10개정도의 페이지가 등록되 있습니다.

그런데 stress tool 의 report 내용을 보면, hit가 1번에만 1번 있고,
나머지는 전부 0입니다.
에러내용도 없고, respose코드도 200으로 나오구요.
콘솔을 보면 2번이후부터는 아예 접근도 안합니다.

별다른 설정이 없는것 같은데.. 세션을 유지해야 하는 다른 설정이 있나요?
세션이 유지가 안된다면, 3번부터 접근이 안되는건 맞긴한데..

기본 셋팅내용은 default로 건드리지 않았구요.
Stress Level 을 1로 (테스트용) Test Run Time 을 1분으로 설정해놓았습니다.

이런건 첨해보는거라.. 도움을 주셨으면 감사하겠습니다. (_ _);



온세상을 자바로~ -_-!!
http://cafe.naver.com/javalove
제목 : Re: OutOfMemory 발생상황에서 Dump를 떳는데요. 해석이..
글쓴이: 손님(guest) 2005/02/03 16:14:55 조회수:1252 줄수:107
실환경에서 모니터링을 하고있는데, 어떤 오류도 아직 발생하지 않았습니다. 아직 이틀동안이지만..
덤프는 걸어놓긴 했는데, 에러가 발생하지 않으니 갑갑하네요.
전체적으로 JVM 힙메모리 차지하는 비율이 점점 증가하고 있습니다.

그래서, 일단 스트레스 테스트 툴로, 테스트를 해봤는데요.
유저 1명, 쓰레드 50, 100 으로 했습니다.
테스트 페이지는 로그인->활동검색->고객검색->기타등등 으로 히트수가 높은것 순으로 
했구요.

50개에선 별무리 없이 갔습니다만, 100개에서 드뎌 OutOfMemory가 발생되며, 덤프가
생기더군요. 그런데 이상한게 익셉션이 엄청난 양을 잡아먹고 있습니다.

아래는 덤프 내용입니다.

Requesting 74 mb of heapspace to process heapdump ...
 done.
Finding pure Roots
...................................................................... done.
DFS from pure Roots
...............................................................        done.
DFS from objects unreached from Roots (6,123)
                                                                       done.
Dump comments        : // Version: J2RE 1.4.2 IBM Windows 32 build
                       cn142-20040926
                       // Breakdown - Classes: 4865, Objects: 3911278,
                       ObjectArrays: 270052, PrimitiveArrays: 1837999
                       // EOF:  Total 'Objects',Refs(null) :
                       6024194,7241268(566154)
Dump has flags       : false
# Objects            : 6,024,194
# Refs               : 7,241,268
# Unresolved refs    : 0
Heap usage           : 534,302,592
Total object range   : 802,536,208

Pure roots           : 9,704
... which reach      : 6,018,071
Artificial roots     : 2,477
Softlinks followed   : 10

HR Memory Usage      : 200/307 mb

Enter: o{a,s,t,d,m,n}, g{c,s}, t{c,s,n}, i, p, d{t,d,m} or help for more info
> d

Enter total-size threshold [1048576]
>
Enter max depth or -ve for unlimited [8]
>
Enter 0x<addr> to dump from one address or any value for all roots [-]
>
Dumping object(s)  : 12181 roots, sorted by total-size
Filter             : total-size >= 1,048,576 and depth at most 8
Prune              : N

<0> [484,054,504] 0x11452960 [32] java/lang/ClassNotFoundException
<1>   [484,054,472] 0x1143ca78 [80] array of java/lang/Object
<2>     [484,053,952] 0x0032ba88 [304] class java/lang/ref/Finalizer
<3>       [483,920,104] 0x1443bdb8 [32] java/lang/ref/Finalizer
<4>         [483,786,368] 0x1443d6c8 [32] java/lang/ref/Finalizer
<5>           [483,652,632] 0x1443b328 [32] java/lang/ref/Finalizer
<6>             [483,518,896] 0x1443a808 [32] java/lang/ref/Finalizer
<7>               [483,385,160] 0x12ddff60 [32] java/lang/ref/Finalizer
<8>                 [483,251,424] 0x12ddf270 [32] java/lang/ref/Finalizer
                      - 4 children of 0x12ddf270 too deep.
<8>                 {483,518,896} 0x1443a808 [32] java/lang/ref/Finalizer
                    - 2 children of 0x12ddff60 filtered.
<7>               {483,652,632} 0x1443b328 [32] java/lang/ref/Finalizer
                  - 2 children of 0x1443a808 filtered.
<6>             {483,786,368} 0x1443d6c8 [32] java/lang/ref/Finalizer
                - 2 children of 0x1443b328 filtered.
<5>           {483,920,104} 0x1443bdb8 [32] java/lang/ref/Finalizer
              - 2 children of 0x1443d6c8 filtered.
            - 2 children of 0x1443bdb8 filtered.
          - 3 children of 0x0032ba88 filtered.
<2>     {484,053,952} 0x0032ba88 [304] class java/lang/ref/Finalizer
<2>     {484,053,952} 0x0032ba88 [304] class java/lang/ref/Finalizer
        - 13 children of 0x1143ca78 filtered.
      - 1 child of 0x11452960 filtered.
<0> [46,408,848] 0x03dd23b8 [304] class java/lang/Shutdown
<1>   [46,408,528] 0x10437350 [16] java/util/HashSet
<2>     [46,408,512] 0x10437320 [48] java/util/HashMap
<3>       [46,408,464] 0x104372d0 [80] array of java/util/HashMap$Entry
<4>         [46,408,240] 0x10842df8 [32] java/util/HashMap$Entry
<5>           [46,408,208] 0x10842e18 [16] java/lang/Shutdown$WrappedHook
<6>             [46,408,192] 0x101eafe0 [96] java/util/logging/LogManager$Clean
r
<7>               [46,408,032] 0x1029cb78 [56] java/lang/ThreadGroup
<8>                 [46,403,504] 0x101f76a8 [56] java/lang/ThreadGroup
                      - 4 children of 0x101f76a8 too deep.
                    - 3 children of 0x1029cb78 filtered.
<7>               <46,400,496 parent:0x101ea978> 0x101eb1c0 [160] org/jboss/mx/
oading/UnifiedClassLoader3
                  - 3 children of 0x101eafe0 filtered.
              - 1 child of 0x10842df8 filtered.
            - 3 children of 0x104372d0 filtered.
      - 1 child of 0x03dd23b8 filtered.

2/12181 roots were dumped. There were 18 objects expanded.

Enter: o{a,s,t,d,m,n}, g{c,s}, t{c,s,n}, i, p, d{t,d,m} or help for more info
>

서버로그를 찾아봐도 ClassNotFoundException 은 발생한적이 없는데,
이게 왜 이렇게 많이 잡아먹은거죠?? 위 덤프를 어찌 해석해야 하는건가요? ㅜ.ㅜ

제목 : Re: IBM JDK에서 Memory Leak의 발경 방법
글쓴이: 조대협(guest) 2005/02/04 09:41:33 조회수:1099 줄수:8
안녕하세요?
조대협입니다. 
Memory Leak의 발견과 조치가 언제나 큰 화두가 되는데요. 이원영님이 언급하신 Heap Dump에 
덧붙여서 Heap dump를 좀더 쉽게 분석할 수 있는 HeapAnalyzer라는 내용을 첨부합니다.

문서 배포는 자유입니다만, 배포시에 출처 명기 부탁드립니다.
수고하세요.

Download 자바스터디_AIX에서_Memory_Leak의_발견.doc (116736 Bytes) 자바스터디_AIX에서_Memory_Leak의_발견.doc (116736 Bytes)
제목 : Re: 그렇군요. 역시 Statement 가 나타나긴 합니다만..
글쓴이: 손님(guest) 2005/02/04 10:24:30 조회수:985 줄수:43
트리뷰 UI로 보니 정말 편하네요. 감사합니다. ^^

한눈에 들어오는것도 좋고, 따라가다 보면, 무엇으로 구성되어 있는지 잡을수 있을것 같습니다.
그래도 ClassNotFoundException은 좀 그렇네요. 자그마치 483메가를 차지하는..
ClassNotFound 따라가보니, ../trace/sql/PreparedStatemnet가 나옵니다.
적은양이긴 하지만, 이것들로 계속 구성된것이 아닌가 싶구요.

일단, Stress Test 결과, Statment 를 수정하지 않고 했을때,
동시유저수 100명에서 OOM이 발생되고, 110 명 120 명씩 늘렸을때,
계속 Reject되는 req들이 여럿 발생했습니다.

수정후에, 다시 몇번 테스트를 해보았는데요.
성능면에선 그리 나아진건 없으나, 일단 Reject되는 건수가 0였습니다.
몇번 테스트 해봤는데, 2~30명에서 2~3건 발생되는것 외엔 나머지 모두 0였죠.
OOM도 전혀 발생한적이 없었습니다. 신기하더군요.. --;

현재 운용중인 시스템은 계속 모니터링 하고있지만, 확실히 Memory Leak이였습니다.
Full GC하위로,  지속적으로 메모리가 누수되고 있었습니다.
몇몇 페이지를 수정하였지만, 이대로 계속가게되면 일주일정도 버틸수 있을것 같던데요.

어쨋든 적어도 주요 핵심 원인은 근거를 바탕으로 밝혀진것 같습니다.
그게 아닌 또다른 원인이 있더라도, 일단 이걸 전부 확실히! 수정하고
또 한 일주일 모니터링을 해봐야 겠습니다.

운영중인 서버를 대상으로 스트레스 테스트를 해보고 싶은데, 그럴순 없어 
안타깝네요.. 

이원영님한테도 정말 감사합니다. 도움이 정말 컷습니다.

%P.S
1)
스트레스 테스트 툴중 원영님이 추천하신 로드런너의 10일짜리 버젼을 받았는데,
스크립트 작성은 되나, 실제로 테스트 단계에서 라이센스가 필요하다고 하며
진행이 더이상 안됩니다. 10일 제한이라도 테스트는 되는거 아닌가요..

2)
여기 게시글 올릴때, 중간에 사진 넣는건 어떻게 하는걸까요?
태그가 먹히는걸까요? 테스트해볼려도 한번올리면 지울수가 없으니..^^;

3) 로그중에 not close pstmt같은것 말구요, 20050203/214126:W:16625 식으로
fetched 되었다고 찍히는 로그내용은 뭔가요? W이랑:수치가 뭘 의미하는지,
강제로 fetch한 내용인가요? 이게 무척 자주 찍히는데요...

Download anal0.JPG (165771 Bytes) anal0.JPG (165771 Bytes)
Download anal.JPG (168703 Bytes) anal.JPG (168703 Bytes)
제목 : Re: 열심히 소스를 수정하세요: pstmt.close()
글쓴이: 이원영(javaservice) 2005/02/04 12:19:39 조회수:1153 줄수:30
..trace/sql/PreparedStatemnet는 tracing을 위한 Wrapping클래스 이름입니다.
HeapDump의 결과가 .../trace/sql/PreparedStatemnet 들로 구성되어 있다는 것은,
PreparedStatement를 close하지 않았다는 증거가 될 수 있습니다.
또한, ...agent.log 파일에 "not close pstmt"라는 것이 곧 해당 URL, 해당 SQL과
관련된 소스코드 근방에서 pstmt.close()를 하지 않았다는 뜻입니다. SQL문장이
함께 로깅되니, 소스의 위치를 찾는 것은 어렵지 않을 것입니다.
서블렛 + JDBC 연동시 코딩 고려사항 -제1탄- 
http://www.javaservice.net/~java/bbs/read.cgi?m=devtip&b=servlet&c=r_p&n=968185187


PS1: 로드런너가 10일짜리, 25유저로 제한되지 않던가요?
PS2: 자바서비스넷의 이미지포함기능은 이미지를 아래에 첨부한 후에, 해당 글의 위치에서
   %% image.gif %% 와 같이 하시면  됩니다.
PS3: 20050203/214126:W:16625:/somewhere/some.jsp?a=b&c=d[3called][2fetched][select..]
 20050203/214126: 로그일자 및 시각
 W: Warning, E: Error
 16625: elapsed time(ms), 16초가 걸렸다는 것이지요.
 [3 called] 해당 요청에서 SQL이 3번 불려졌다는 것이구요
 [waiting] : ds.getConnection()에서 JDBC Connection Pool에서 가용한 연결을 기다리는 중
 [preparing] 해당 SQL을 conn.prepareStatement(...)수행중
 [prepared] 해당 SQL을 conn.prepareStatement(...)를 끝냈다는 뜻
 [executing] 해당 SQL을 현재 수행중이라는 뜻(pstmt.executeUpdte/Query())
 [4 fetching]: 현재 rs.next() 를 4번 돌고 있으며 진행중
 [10 fetched] : 현재 rs.next()를 끝냈고, 현재까지 rs.next()를 10회 돌았다는 뜻


자바서비스컨설팅 이원영
Phone: 010-6239-6498
E-mail: lwy@javaservice.com
MSN: javaservice@hanmail.net
제목 : Re: 오류수정이후 힙메모리 모니터링 결과입니다.
글쓴이: 김영근(naucika) 2005/02/17 11:04:49 조회수:1193 줄수:13
15일, 16일, 17일 3일치인데요.
이정도면, 정상적이라고 얘기할 수 있을까요?
그리고, 3일차에 갑자기 100메가 정도로 떨어져 버리네요? GC가 발생한건가요?
2일이나 지나서 GC가 이렇게 대량의 메모리를 제거하는건가요? 제가 알기론
어느정도 시스템 유휴상태가 되면, 꽤 자주 하는것으로 알고있는데. 100메가정도가
제거된 이유가 GC때문이 맞을까요?
사용자 삽입 이미지
사용자 삽입 이미지
제목 : Re: GC 그래프에 대한 의견
글쓴이: 조대협(guest) 2005/02/18 09:58:11 조회수:1252 줄수:7
전체 Heap이 1G 인가요?
거의 200~300M정도의 수준에서 머무는데.. 
제 의견으로는 아주 상당히 안정적인 것으로 보입니다.
시스템의 부하가 그리 많지 않나보네요. 100M가량 갑자기 떨어지는것은 Full GC가 일어났다고
보이는데요. GC로그에서 FullGC가 저시간즈음 일어나지 않았는지 확인해보세요.
수고하세요.
Posted by 알 수 없는 사용자
|