2017-06-28 14 views
1

私はタイムスタンプ(long)とオブジェクト(safeboxForLongString)を持つマップを含むオブジェクトでいっぱいになるmysqlデータベースを持っています。MySQLとJava - メモリの問題

セーフボックスの文字列は5〜15MBです。

私の問題は、サーバーからStringデータを要求してから約30分後、私のRAMメモリはすでに11-12 GBになっています。私は既にSystem.gcを呼び出して、以前に塗りつぶされたTreeMapをクリアしようとしました。しかし、成功はありません。

私のすべてのRAMを使用する必要はありませんバックアップされたデータベースの目的はありませんか?

私はその問題で常に失敗するため、サーバーデータの収集プロセスを完了できません。私を助けてください。

ここでは、関連するコード

//fill the Database 
    Main.getAllAvailableEntries().forEach(entryName -> { 

     final long[] id = {0}; 
     treeMapWrapperRepo.findAll().forEach(entry -> { 
      if (entry.getCurrency().equals(entryName)) { 
       id[0] = entry.getMultiHashMapWrapper_id(); 
      } 
     }); 

     if (id[0] == 0) { 
      System.out.println("Forming: " + entryName); 
      final TreeMapWrapper treeMapWrapper = new TreeMapWrapper(entryName); 
      TreeMap<Long, SafeBoxForLongString> timeStampToSafeBoxMap = new TreeMap<>(); 
      int start = startDateInThePast; 
      while (start - length >= 0) { 
       long startDate = instant.minus(start, ChronoUnit.DAYS).getEpochSecond(); 
       long endDate = instant.minus(start - length, ChronoUnit.DAYS).getEpochSecond(); 

       String getReponseWith45DaysLength = dataController.getDataForDB(entryName, startDate, endDate, String.valueOf(resolution)); 
       while (getReponseWith45DaysLength.isEmpty()) { 
        getReponseWith45DaysLength = dataController.getDataForDB(entryName, startDate, endDate, String.valueOf(resolution)); 
       } 

       SafeBoxForLongString safeBoxForLongString = new SafeBoxForLongString(getReponseWith45DaysLength); 
       safeBoxForLongString.setMultiHashMapWrapper(treeMapWrapper); 

       timeStampToSafeBoxMap.put(startDate, safeBoxForLongString); 
       treeMapWrapper.setLongSafeTimeAndReponseMap(timeStampToSafeBoxMap); 

       start--; 
      } 
      treeMapWrapperRepo.save(treeMapWrapper); 
      treeMapWrapper.getLongSafeTimeAndReponseMap().clear(); 
      System.gc(); 
     } 
    }); 

編集:1台のスタッカーが言ったように、treeMapWrapperRepo.findAll()。問題だった。

+0

gcを呼び出すときにオブジェクトを参照していないことは間違いありませんか?プロファイラでこれを見てみましたか? –

答えて

1

表示されるエラーはほとんどありません。まず、データベースからすべてのエントリを取得しています。これらのエントリは、ディスク(DB)からRAM(Javaオブジェクト)に直接ロードされます。

ガベージコレクタは、参照されていないオブジェクトまたは分離されたオブジェクトを調べます。これを知っていると、私はコードをリファクタリングし、リポジトリ側のページネーションを使用して、一度に10項目または他の適切な値をロードします。検索されたすべてのオブジェクトをリストに格納せず、必要なオブジェクトのみを格納します。変数をnullに設定すると、GCにヒントを与えることができます。

また、このMain.getAllAvailableEntries()がどこからデータを取得するのかわかりません。この問題は、treeMapWrapperRepo.findAll()ではなく、そこにある可能性があります。

ドミニクがコメントに示唆しているように、プロファイラとデバッガを使用してみてください。これは、あなたがメモリを漏らしているヒントを与えるでしょう。

+0

Main.getAllAvailableEntries()は、サーバがもう一方の端で必要とする文字列を取得するだけです。リストは200文字の短い文字列です。 treeMapWrapperRepo.findAll()を使ったアイデア。私はそれについて考えなかった。あなたは良いプロファイラーを提案することはできますか?また、treeMapWrapperRepo.findAll()の場合。問題です。データベース内のオブジェクトの特定のIDを反復処理せずに特定のIDを見つけるにはどうすればよいですか? – AnnaKlein

+0

私はいつもNetbeansの埋め込みプロファイラ、またはNetbeansやIntellijのデフォルトのデバッガを使用してきました。 –

+0

リポジトリの実装にSpring Dataを使用している場合は、Streamingオプションを確認してください。 DBからフェッチされた結果を処理します:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-streaming –