0

Below Java syntax is throwing Java memory Heap issue in Openshift while invoking the data from the Mongodb database.Is there any way to know where the memory leakage is happening.Is memory will be reduced if we use Java 8 for each streams instead of for loop .Can anyone help me with Java8 for each synatx with the Pojo class .Here Amount is the POJO class. Or Any other suggestions also can be appreciated to reduce the memory for too many requests.

public String getAmountDetails( @RequestParam("system") @Valid String system,
                                 @RequestParam("Claims") BigDecimal Claims,
                                 @RequestParam("Bills") BigDecimal totalOfCommissions,
                                 @RequestParam("taxes") BigDecimal totalOfSurcharges,
                                 @RequestParam("userDetails") BigDecimal userDetails,
                               ) throws Exception {

        Query Query = new Query();
       
        if (system != null && !system.isEmpty())
           Query.addCriteria(Criteria.where("system").is(system));
        List<Amount> amount = new ArrayList<>();
       
        amount = mongoOps.find(Query, Amount.class);
        amount.addAll(Amount);
       
        totalAmount = new Amount();
        if (Amount.isEmpty()) {
            totalAmount.setSystem(system);
            totalAmount.setClaims(BigDecimal.ZERO);
            totalAmount.setBillsBigDecimal.ZERO);
            totalAmount.setTaxes(BigDecimal.ZERO);
            totalAmount.setuserDetails(BigDecimal.ZERO);
            totalAmount.setStatus("Success");
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(totalAmount);
        }
        BigDecimal claims = new BigDecimal(0);
        BigDecimal bills = new BigDecimal(0);
        BigDecimal taxes = new BigDecimal(0);
        BigDecimal userDeatils = new BigDecimal(0);
      
       
        for (Amount amount : getAmount) {
            if (null != amount.getClaims()) {
                claimsAmt = claimsAmt.add(amount.getclaimsAmt().bigDecimalValue());
            }
            if (null != amount.getBillsAmt()) {
                billslAmt = billsAmt.add(amount.getBillsAmt().bigDecimalValue());
            }
            if (null != amount.gettaxesAmt()) {
                taxesAmt = taxesAmt.add(amount.getTaxesAmt().bigDecimalValue());
            }
            totalAmount.setClaims(claimsAmt);
            totalAmount.setbills(billsAmt);
            totalAmount.settaxesAmt(taxesAmt);
        }
       
    }
Rose
  • 89
  • 5
  • 18

1 Answers1

0

To start with - your foreach loop is ok, besides the fact that you haven't shown what is getAmount over which you're iterating. So assume its a typo and basically you ask mongo to bring you all the "Amount" objects by some criteria and all this only to calculated the sum of some values.

If there are many objects in the database, this will be:

  • Slow
  • Memory Consuming

I wouldn't say there is a leak here, just an ineffective flow. In OpenShift you might work with some "serious" environment and if there are many requests running on a big amount of objects simultaneously you might end up with OutOfMemory indeed.

To start with the verification of this theory you may log a number of objects that you get from mongo (size of the amount list). If you have pretty big numbers, continue reading.

Now in terms of solution:

So maybe you should ask mongo to calculate a sum for you instead of doing it in Java. Mongo will handle that even if there are many documents in the collection.

I haven't used mongo for a lot of years, but it has an aggregation framework with $sum that should be used.

Read This SO thread as they provide an example of how to achieve a similar task in mongo.

Also you can Read this thread for even slightly more complicated example that you did.

Here is a link to mongo documentation that can come handy as well

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97