2017-06-01 13 views
1

私は170kアイテムと20-150個の機能を持つ各アイテムからなる大きなデータベースを持っています。このデータを、item_idとフィーチャのリストで構成されるマップに取得するメソッドを実行すると、Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededが得られます。メソッドは約30分実行され、例外がスローされます。MySQLクエリでGCオーバーヘッドの上限を超えました

public Map<Integer, List<ItemFeatureMapping>> getItemFeatures() { 
    List<Item> allItems = getAllItems(); 
    Map<Integer, List<ItemFeatureMapping>> result = new HashMap<>(); 
    for (Item i : allItems) { 
     List<ItemFeatureMapping> itemFeatures = new ArrayList<>(); 
     for (ItemFeatureMapping feature: i.getItemFeatures()) { 
      itemFeatures.add(feature); 
     } 
     result.put(i.getId(), itemFeatures); 
    } 
    return result; 
} 

私はマニュアルに見えた:あまりにも多くの時間 がガベージコレクションに費やされている場合は、並列コレクタはOutOfMemoryErrorが発生をスローします

:ここでの方法である場合の98%以上合計で の時間がガベージコレクションに費やされ、ヒープの2%未満が回復された場合、 が返されます。OutOfMemoryErrorがスローされます。この機能は、 の時間がアプリケーションの実行を妨げないように設計された です。ヒープのサイズが小さいため、処理がほとんどまたはまったく行われません。 です。必要に応じて、コマンドラインにオプション -XX:-UseGCOverheadLimitを追加することで、この機能を無効にすることができます。

これをどのように並べ替えることができますか?または、メソッドを最適化することは可能ですか?

P .:私はコマンドラインで実行しようとしましたが、エラーが発生しましたCommand not found。しかし、この方法は、長い時間実行されている可能性があるので、私はこの解決策が気に入らない。代わりに、すべてのループ実行のための新しいitemFeaturesオブジェクトを作成する

+0

-Xmx4gパラメータを使用してjvmのヒープサイズを増やすことができます。 – dabaicai

答えて

1

ますあなたのリストallItemsitem.getItemFeatures()から処理されたアイテムをすべて削除することができますターゲットマップ/リストに追加しました。このアイテムによって使用されるメモリは、作成したマップ/リストによってガベージコレクションされ、再利用されます。

さらに、コンストラクタで予想されるサイズでコレクションを初期化できます。こうすることで、あなたのコレクションのエントリーのために割り当てられているが決して使用されなかった場所でメモリを無駄にすることはありません。

これで問題が解決しない場合は、ヒープサイズを大きくする必要があります。そうでないと、すべての機能の表現が割り当てられたメモリに収まらないからです。

public Map<Integer, List<ItemFeatureMapping>> getItemFeatures() { 
    List<Item> allItems = getAllItems(); 
    Map<Integer, List<ItemFeatureMapping>> result = new HashMap<>(allItems.size(), 1f); 
    Iterator<Item> iterator = allItems.iterator(); 
    while (iterator.hasNext()) { 
     Item item = iterator.next(); 
     List<ItemFeatureMapping> itemFeatures = new ArrayList<>(item.getItemFeatures().size()); 

     Iterator<ItemFeatureMapping> iteratorFeature = item.getItemFeatures().iterator(); 
     while (iteratorFeature.hasNext()) { 
      ItemFeatureMapping feature = iteratorFeature.next(); 
      itemFeatures.add(feature); 
      iterator.remove(); 
     } 
     result.put(item.getId(), itemFeatures); 
     iterator.remove(); 
    } 
    return result; 
} 
0

、あなたはループの外に一度リストのインスタンスを作成し、

itemFeatures.clear(); 

そして、@dabaicaiが述べたように、それをより多くのJVMを与えてみてくださいを使用してリストをクリアすることができますヒープサイズ。

また

、問題を速くデバッグを支援するために、このよう

  • Javaバージョン
  • ヒープサイズとして可能なすべての情報を含めるようにしてみてください
  • JVMパラメータ
+1

あなたのソリューションでは、すべてのキーが同じ値(itemFeatures)を保持しますが、正しくはないと思います。 – dabaicai

関連する問題