2017-09-07 1 views
4

톰캣 8.5을 VisualVM과를 사용하고 검사에서 OutOfMemory Java 힙 공간은 내가 볼 로그 catalina.out 거의 때마다 (7 11 회 중 정도) 전체 GC 그 로그가 표시됩니다. OutOfMemory (정확히 같은 분). 톰캣으로자바 8 완전 GC와

매개 변수 메모리 관리를 함께 할 수있는 뭔가가 : 처음에는 MaxHeapFreeRatio = 100

: -Xms3G -Xmx = 6 세대 -XX : + UseG1GC -XX : + UseStringDeduplication -XX을 나는 그게 기본값이라고 생각했기 때문에 -XX : MaxHeapFreeRatio 값은 입니다. 힙 크기 (물론 사용 된 힙)는 크게 감소합니다. 전체 GC - ~ ~ 10-20 %입니다. 그러나 XX : MaxHeapFreeRatio = 100을 추가해도 문제가 해결되지 않았습니다. 이 비록

JVM의 다른 세트 메모리 사용량 그래프입니다 매개 변수 (구 JVM과 함께 일을 얻을 수없는 것은 ATM 매개 변수)가 전체 GC 메모리 후 방식과 유사 사용량 은 빠르게 증가합니다., 최대. 힙 크기와 최대 크기. 힙 크기가 떨어지지 않습니다.

enter image description here

이 일어날 수있는 이유가 뭘까요?

업데이트 : - ~ 5기가바이트 힙 크기 도 완전하지 때 나는에서 OutOfMemory이 일어날 것 이전에 전체 GC 언급하는 것을 잊었다. 그 당시에는 한 번도 아니었지만 힙이 6GB에 도달하는 것을 보았습니다.

+0

이러한 JVM GC 매개 변수를 조정해야합니다. http://blog.sokolenko.me/2014/11/javavm-options-production.html – duffymo

+0

이와 같은 질문을하기 전에 프로파일 링을 수행하십시오. 예를 들어 YourKit을 사용할 수 있습니다. 경우에 따라 GC가 너무 많은 오브젝트를 생성하여 릴리스 할 수없는 상황이 발생할 수 있습니다. – tsolakp

답변

1

분명히 생성 된 개체 중 일부는 제대로 가비지 수집 할 수 없습니다. VisualVM의 샘플러 기능을 사용하여 생성 된 인스턴스 수를 추적 할 수 있습니다.

+0

당신이 맞습니다. OOM이 의미하는 것입니다. 그러나 1GB 정도의 여유 공간이 남았을 때 (예 : 업데이트보기) 전체 GC가 발생할 때 OOM이 발생할 수있는 방법입니다. – user435421

+0

여기에는 몇 가지 이유가있을 수 있습니다. permgen 공간이 꽉 찼거나 대규모 배열이나 객체 생성에 사용할 수있는 연속 메모리 블록이 없거나 GC 시간이 너무 길면 배열 크기가 jvm 한계를 초과했습니다. – Alex

0

IO 작업을 MapDB으로 캐시하십시오.

당신은 디스크 기반 파일 데이터베이스에 캐시 같이 할 수

: 다음

import java.io.File; 
import java.io.IOException; 
import java.util.Map; 
import org.mapdb.DB; 
import org.mapdb.DBMaker; 

/** 
* Singleton class. 
*/ 
public class DBManager 
{ 
     /** 
    * Variables. 
    */ 
    private static File dbFile = new File("path/to/file"); 
    private DB db; 
    private static final String password = "yourPassword"; 
    private Map<Integer, String> ctDB; 
    private static DBManager manager; 

    /** 
    * Singleton operations. 
    */ 

    /** 
    * Static initializer. 
    */ 
    static 
    { 
    manager = null; 
    } 

/** 
* Singleton method @see DBManager.getInstance(File dbFile); 
* @return   -> An object/instance of this class. 
*/ 
public static DBManager getInstance() 
{  
    if(isFileDatabaseOK()) 
    { 
     /** 
     * Check if an object/instance from this class exists already. 
     */ 
     if(manager == null) 
     { 
      manager = new DBManager(); 
     } 

     /** 
     * Return an object/instance of this class. 
     */ 
     return manager; 
    } 
    else 
    { 
     return null; 
    } 
} 

/** 
* Constructors. 
*/ 

/** 
* Empty default Constructor starts the MapDB instance. 
*/ 
private DBManager() 
{  
    /** 
    * Load the database file from the given path 
    * and initialize the database. 
    */ 
    initMapDB(); 
} 

/** 
* MapDB initializer. 
*/ 

/** 
* Initialize a MapDB database. 
*/ 
private void initMapDB() 
{ 
    /** 
    * Persistence: Make MapDB able to load the same database from the 
    * file after JVM-Shutdown. Initialize database without @see  org.mapdb.DBMaker.deleteFilesAfterClose() 
    * @see <link>https://groups.google.com/forum/#!topic/mapdb/AW8Ax49TLUc</link> 
    */ 
    db = DBMaker.newFileDB(dbFile) 
      .closeOnJvmShutdown()  
      .asyncWriteDisable() 
      .encryptionEnable(password.getBytes()) 
      .make(); 

    /** 
    * Create a Map/Get the existing map. 
    */ 
    ctDB = db.getTreeMap("database"); 
} 

/** 
* File existence check. 
* If file doesn't exists -> Create a new db file and inform the user. 
*/ 
private static boolean isFileDatabaseOK() 
{  
    /** 
    * If the file doesn't exists (First run) create a new file and 
    * inform the user. 
    */ 
    if(!dbFile.exists()) 
    { 
     try 
     { 
      dbFile.getParentFile().mkdirs(); 
      dbFile.createNewFile(); 

      /** 
      * TODO 
      * System.out.println("Database not found. Creating a new one."); 
      */ 

      return true; 
     } 
     catch (IOException e) 
     { 
      /** 
      * TODO Error handling 
      */ 
      e.printStackTrace(); 
      return false; 
     } 
    } 
    else 
    {   
     return true; 
    } 
} 

/** 
* Database methods/operations. 
*/ 

/** 
* Get objects by id. 
* @param id -> Search parameter. 
* @return  -> The object that belongs to the id. 
*/ 
public String get(int id) 
{ 
    return ctDB.get(id); 
} 

/** 
* Adding objects to the database. 
* @param id -> The key reference to the object as 'id'. 
* @param object -> The object to cache. 
*/ 
public void put(int id, String object) 
{ 
    ctDB.put(id, object); 

    db.commit(); 
} 
} 

그리고는 이렇게 : 당신은 대부분 기본 값을 설정하면

DBManager manager = DBManager.getInstance(); 
manager.put(1, "test"); 
Sytem.out.println(manger.get(1)); 
0

G1GC 잘 작동 매개 변수. 키 매개 변수 만 설정하십시오.

-XX:MaxGCPauseMillis 
-XX:G1HeapRegionSize 
-XX:ParallelGCThreads 
-XX:ConcGCThreads 

기타 항목은 모두 Java로 설정하십시오.

당신은 게시물 아래에서 자세한 내용을 찾을 수 있습니다

Why do I get OutOfMemory when 20% of the heap is still free?

Java 7 (JDK 7) garbage collection and documentation on G1는 사용 mat 같은 일부 메모리 분석 도구는 근본 원인을 알고.

귀하의 경우, oldgen이 증가하고있는 것이 분명합니다. 메모리 누출 가능성을 검사하십시오. 메모리 누수를 찾지 못하면 힙 메모리를 추가로 늘리십시오.