2011-07-17 6 views
3

메모리 오류가 발생하여 JVM 인수를 설정하여 JSF 응용 프로그램 메모리 consuption을 조정하려고합니다. ,java.lang.OutOfMemoryError : Java 힙 공간 - 메모리를 절약하는 방법?

-XX:+UseConcMarkSweepGC 
-XX:+UseParNewGC 
-XX:+CMSClassUnloadingEnabled 
-XX:+CMSParallelRemarkEnabled 
-XX:CMSInitiatingOccupancyFraction=30 
-XX:+CMSIncrementalMode 
-XX:+CMSIncrementalPacing 
-XX:ParallelCMSThreads=2 
-XX:+UseCMSCompactAtFullCollection 
-XX:+DisableExplicitGC 
-XX:MaxHeapFreeRatio=70 
-XX:MinHeapFreeRatio=40 
-XX:MaxTenuringThreshold=30 
-XX:NewSize=512m 
-XX:MaxNewSize=512m 
-XX:SurvivorRatio=2 
-XX:PermSize=150m 
-Xms1024m 
-Xmx1024m 

모든 것이 잘 작동하는 것 같다 :

JVM 인수 ...

나는 메모리 힙을 증가시키고 하루에 두 번 서버를 다시 시작할 수 있어요,하지만 해결책이 아니다 테네시 공간은 0MB이지만 에덴 공간은 연속적으로 지워지지 만 생존 공간은 여전히 ​​커지고 한계에 도달하면 객체는 테넌트 공간으로 옮겨지며 결코 해제되지 않습니다. 그리고 응용 프로그램을 실행하는 반나절 후 나는 메모리 부족 오류가 발생합니다. 그래서 Tomcat 서버의 자동 재시작을 예약해야합니다. 메모리의 소비가 (하루 데이터베이스에 수천의 움직임에 대해) 같은 작은 APPL 너무 높기 때문에

enter image description here

그래서 난 내 응용 프로그램에서 일부 문제가있을 수 있어야합니다 생각합니다.

Bean.java

/* save datalist */ 
public void save() 
{ 
    session = DaoSF.getSessionFactory.openSession(); 
    try 
    { 
    Dao.save(dataList); 
    } 
    catch (Exception e) {...} 
    finally 
    { 
    session.close(); 
    } 
} 

public static void save(List<? extends Object> dataList) 
{ 
    for (Object dataItem : dataList) 
    { 
    save(dataItem); 
    } 
} 
public static void save(Object dataItem) 
{ 
    try 
    { 
    Transaction tx = session.beginTransaction(); 
    session.save(dataItem); 
    tx.commit(); 
    } 
    catch(Exception e) {....} 
} 

DaoSF.java

01 Dao.java
:

내 코드의 일부가

저장된 개체가 메모리에 남아 있지 않도록 개체를 데이터베이스에 저장 (업데이트, 삭제)하는 것이 가장 좋은 방법은 무엇입니까?

+0

는 어디 세션 객체를 저장할 수 있습니까? 오라클 세션입니까? 특히 DAO에서는 메서드가 정적 인 관계로? – home

+0

BTW : 세션이 DAO 안에 캡슐화되어야한다고 생각합니다. – home

+0

잘 모르겠지만 메모리 누수가 발생하기 때문에 정적 인 것들을 피하는 것이 항상 좋은 습관이라고 들었습니다 –

답변

3

시도해보십시오. 아직 완벽하지는 않지만 Dao의 정적 세션 속성을 제거해야한다고 생각합니다. 최대 절전 모드 문서 참조 : http://docs.jboss.org/hibernate/envers/3.5/javadocs/org/hibernate/Session.html :

구현자가 스레드 안전을 보장하지 않습니다. 대신에 각 쓰레드/트랜잭션은 SessionFactory로부터 그것 자신의 인스턴스를 얻어야한다.

가 기본 지속성 메커니즘에 대한 지식이없는 있도록 또한, 다오 자체 내부의 세션을 얻을 수 있습니다,하지만 난 그렇게 많이 변경하지 않았다.

는 Bean.java

/* save datalist */ 
public void save() { 
    Session session = nlul; 
    try { 
     session = DaoSF.getSessionFactory.openSession(); 
     /* one instance per call, 
     * ready for garbage collection after leaving this method 
     */ 
     Dao mydao = new Dao(session); 
     mydao.save(dataList); 
    } catch (Exception e) {... 
    } finally { 
     if (sessioN != null) 
      session.close(); 
    } 
} 

Dao.java는

private Session mysession = null; 

public Dao(Session mysession) { 
    this.mysession = mysession; 
} 

public void save(List<? extends Object> dataList) { 
    for (Object dataItem : dataList) { 
     save(dataItem); 
    } 
} 

public void save(Object dataItem) { 
    try { 
     Transaction tx = session.beginTransaction(); 
     this.mysession.save(dataItem); 
     tx.commit(); 
    } 
    catch(Exception e) {....} 
} 
+0

고맙습니다. 집에 돌아 왔습니다! 그리고 나는 어떤 코드를 작성하기 전에 먼저 생각해야한다 :) – gaffcz

+0

@ gaffcz : No prob. 솔직히 말해서 이것이 결국 당신의 문제를 해결하는지 모르겠습니다. 그러나 OOM 예외를 자세히 살펴보기 전에이 문제를 해결해야합니다. – home

+0

대단히 고마워요! 나는 DaoSF.java simillary를 rewrited했고 클래스는 사용하지 않았지만 클래스의 인스턴스를 사용했다. 그리고 정적 메소드 몇 개 (예 : 시간 계산 등)가 있습니다. 동일한 방법으로 다시 작성해야합니까? 또는 J2EE appl의 일부 메소드를 정적으로 사용하는 것이 정상입니까? – gaffcz

2

"PermGen : Out of Memory"가있는 경우 에덴, 생존자 또는 정규직 공간과 관련이 없습니다.

Permgen에서 "힙이 아닌"부분 인 -XX : PermSize = 150m과 관련되어 있습니다. 더 큰 크기로 시도해보십시오.

그렇지 않으면 클래스가 할당 된 메모리를 차지할 수있는 JSP/servlet 컴파일러/클래스 로더/스프링에서 메모리 누수가 발생할 수 있습니다. 인스턴스 수 또는 프록시 생성 클래스가 아닌

+0

고맙습니다. 이전에 PermSize를 늘려 고했지만 그림에서 볼 수 있듯이 힙이 아닌 부분은 OK입니다. – gaffcz

+0

+1 - permgen 공간에 대한 관찰 용입니다. –

+0

@jaime - 예외 메시지에 "PermGen : out of memory"가 표시되면 permgen 메모리가 부족합니다. 모니터링 그래프를 잘못 해석하고 있습니다. –

4

데이터베이스의 개체를 저장/삭제/업데이트하는 것과 관련하여 메모리 관련 문제가 발생할 가능성은 거의 없습니다. PermGen 공간은 일반적으로 사용자 수준 개체에 사용되지 않습니다. 그것은 같은 클래스 정의, JVM 상태의 내부 비트 등의 할당이 해제되지 결코 에 의미 일에 사용됩니다.

가 있었다면 데이터 개체를 어떻게 관리하고 있는지에 관한 문제로 힙 공간이 남아 있다는 불평이있는 OutOfMemoryError이 표시 될 수 있습니다. 그러나 질문에 대답하기 위해 일반적으로 데이터 객체는 범위를 벗어난 후 실행되는 다음 가비지 수집 단계에서 가비지 수집됩니다 (즉, 아무 곳이나 참조하지 않음). OutOfMemoryError 문제가 발생하지 않으므로이 벌금을 이미 처리하고있는 것으로 의심됩니다.

PermGen 영역을 벗어난 경우 응용 프로그램이 많은 라이브러리를 사용하고 있기 때문일 수 있습니다. 슬프게도,이 문제를 해결하는 유일한 방법은처럼 PermGen 크기를 증가시키는 것이다 : 이것은 기본적으로 응용 프로그램에서 사용할 수 힙 공간의 양을 감소 것

-XX:PermSize=256m

주, 그래서 보통 현명하다 같은 상응하는 금액으로 총 JVM 메모리 할당을 증가 :

-Xmx1130m

는 시도를주고 당신을 위해 더 나은 작동하는지 확인.

+0

정말 미안 해요,'java.lang.OutOfMemoryError : Java heap space'입니다. 나는 바보입니다. permSize 및 힙 크기를 변경하려고 시도했지만 sulution이 아닙니다. 나중에 추가 할 시간이 있기 때문에 나중에 Tomcat 서버를 다시 시작할 수 있습니다 ... – gaffcz

관련 문제