アプリケーションでかなり深刻なメモリリークが発生しました。Morphiaを使用してMongoに一括書き込みしようとすると、パフォーマンスが急速に低下し、低下し続けます。(つまり、最初の100レコードは書き込みに1秒未満かかり、レコード8899から9000は310秒かかります。)
Yourkitを使用すると、com.mongodb.BasicDBObject、com.mongodb.DBRef、com.mongodb.BasicDBListの保持サイズが非常に高く(41〜81%)、保留中のファイナライズとして継続的に報告されます。
さらに、代わりにディスクに書き込むようにdatastore.save(...)を変更しても、パフォーマンスの低下は見られません。
現在、MongoOptionsを使用していません。私はすべきですか?アプリケーションのパフォーマンスを向上させるために利用できる調整は何ですか?
私はmongojavaドライバーバージョン2.7.0とmorphia0.99.1-SNAPSHOTを使用しています。
単純なforループでコントローラーメソッドを呼び出します。
@RequestMapping(value = "/reports", method = RequestMethod.POST, headers = "Accept=application/json")
public ResponseEntity<Result> add(@RequestParam("title") String title,
@RequestParam("uri") String uri,
@RequestParam(value = "imageUri", required = false) String imageUri,
@RequestParam(value = "categoryIds", required = false) List<String> categoryIds,
@RequestParam(value = "expertsIds", required = false) List<String> expertIds,
@RequestParam(value = "userId", required = false) String userIdString,
@RequestParam(value = "description", required = false) String description) {
if (imageUri == null) {
imageUri = "";
}
List<Category> categories = new ArrayList<Category>();
if (categoryIds != null && !categoryIds.isEmpty()) {
categories = categoryService.getCategoriesById(categoryIds);
}
Report report = new Report(StringEscapeUtils.escapeHtml(title), uri, imageUri, categories, expertIds, description);
UUID userID = userService.convertUserId(userIdString);
Result result = userService.addReport(userID, report);
return new ResponseEntity<Result>(result);
}
public Result addReport(UUID userID, Report report) {
Result result = reportService.add(report);
if (!result.getErrorMessages().isEmpty()) {
return result;
}
if (!doesUserExistInDb(userID)) {
createUserWithId(userID);
}
updateUserWithReport(userID, report);
return result;
}
public Result add(Report report) {
Result result = new Result();
try {
datastore.save(report);
result.addReport(report);
} catch (ConstraintViolationException ex) {
populateValidationErrors(result, ex);
}
return result;
}
public void updateUserWithReport(UUID userID, Report report) {
User user = datastore.get(User.class, userID);
user.getReports().add(report);
datastore.save(user);
}