2017-09-07 18 views
4

のTomcat 8.5をVisualVMのを使用してチェックのOutOfMemory Javaヒープスペースは、私が見ログcatalina.out ほとんどたびに(7〜11回のうち程度)フルGCいますログ表示OutOfMemory(まったく同じ分)。 -Xms3G -Xmx = 6G -XX:+ UseG1GC -XX:+ UseStringDeduplication -XX:MaxHeapFreeRatio = 100Javaの8フルGCと

まずTomcatのメモリ管理とは何かを持っているパラメータ

私はそれがデフォルトのためだと思った-XX:MaxHeapFreeRatio値はです。ヒープサイズ(および使用されたヒープはもちろん)完全なGC - 〜〜10-20%の間に大幅に低下します。ただし、XX:MaxHeapFreeRatio = 100を追加しても修正されませんでした。

これは異なるJVMが(古いJVMと1のATMパラメータを取得することはできません)、それはフルGCメモリの後のように似ているパラメータのセットメモリ使用量のグラフですが、使用は急速に成長します。、同じ最大。ヒープサイズとその最大値。ヒープサイズは低下しません。

enter image description here

これが起こる可能性がなぜ任意のアイデア?

アップデート:私は、ヒープサイズでもフルではなかったとき、以前フルGCにOutOfMemoryが起こることを言及するのを忘れてしまった - 〜5ギガバイト当時、私はヒープが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

MapDBを使用してIO操作をキャッシュするようにしてください。

あなたは、ディスクベースのファイルのデータベースにそれをキャッシュするために、次のように行うことができます。

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にします。

あなたはポスト以下で詳細を見つけることができます。

Java 7 (JDK 7) garbage collection and documentation on G1

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

根本的な原因を知るためにmatのようないくつかのメモリ分析ツールを使用してください。

あなたのケースでは、oldgenが成長していることは明らかです。メモリリークの可能性がないか確認してください。メモリリークが見つからなかった場合は、ヒープメモリをさらに増やしてください。

関連する問題