Утечка памяти при использовании Mongo с Morphia - PullRequest
2 голосов
/ 18 февраля 2012

Я обнаружил довольно серьезную утечку памяти в моем приложении.При попытке выполнить массовую запись в Mongo с использованием Morphia производительность быстро падает и продолжает снижаться.(т. е. начальные 100 записей занимают <1 секунды для записи, записи с 8899 по 9000 занимают 310 секунд.) </p>

Используя Yourkit, я вижу, чем com.mongodb.BasicDBObject, com.mongodb.DBRef, com.mongodb.BasicDBListимеют очень высокие сохраняемые размеры (41-81%) и постоянно сообщают об ожидающей финализации.

Кроме того, если я изменяю datastore.save (...) для записи на диск, я не вижу снижения производительности.

В данный момент я не использую MongoOptions.Должна ли я быть?Какие настройки доступны для улучшения производительности моего приложения?

Я использую драйвер Mongo Java версии 2.7.0 и morphia 0.99.1-SNAPSHOT.

Я вызываю метод контроллера впростой цикл:

@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);
}
...