DKG
DKG

Reputation: 387

My Java app running out of memory

My application is running out of memory while performing an operation with a large data. The data is a Java List and is around 100K elements in size. PersistData is the class which implements the operation and PersistDataIntoDB is the class which does the actual operation. Because the operation time consuming, the caller to PersistData gets a response saying the operation is started and there are additional APIs to get the status of the operation.

Also, the entire operation in concurrent and there are multiple callers to the operation.

Here is what the code looks like (I hope its readable).

public class PersistData {
    public Boolean persistData(List<ClassA> dataRecs) {
        //some checks (smaller operation)
        persistDataInDifferentThread(dataRecs);
        //if no errors in checks return true
        return true;
    }

    private void persistDataInDifferentThread(List<ClassA> dataRecs) {
        Thread runnerThread = new Thread(new Runnable() {
            public void run() {
                try {
                    List convertedList = constructClassBUsingClassA(dataRecs);
                    PersistDataIntoDB dbPersist = new PersistDataIntoDB();
                    dbPersist.persistDataInDB(convertedList);
                }
                catch (Exception e) {
                }
            }
        });
    }

     private List<ClassB> constructClassBUsingClassA(List<ClassA> dataRecs) {
    List<ClassB> tempList = new ArrayList<ClassB>();
    for (int i = 0; i < dataRecs.size(); i++) {
        ClassA tempRec = dataRecs.get(i);
        ClassB tempRecB = new ClassB();
        //put stuff from tempRec to tempRecB
        tempList.add(tempRecB);
    }
    return tempList;
}

}

Class which does the persistance.

public class PersistDataIntoDB {
     public Boolean persistDataInDB(List<ClassB> dataRecs){
        //if all goes well return true
        return true;
    }
}

My question is if my method persistDataInDifferentThread can be refactored ?because while it is running, there are two large Lists in memory and the call to persistDataInDB take long time to finish and the garbage collector may not be unloading the List<ClassA> even though I don’t need it after calling persistDataInDB.

Is my above analysis wrong? I just have to increase the max heap because I am dealing with large data?

Upvotes: 0

Views: 235

Answers (1)

Stephen C
Stephen C

Reputation: 718788

Is my above analysis wrong? I just have to increase the max heap because I am dealing with large data?

Yes, and yes.

1) Using multiple threads does not increase or reduce the amount of heap space used.

2) If the heap fills up, then the JVM will make every effort to reclaim space before throwing an OOME.

The only thing that might make a difference is if one thread creates the list and passes it to the second instance to be persisted ... and also hangs onto a reference to the list. That might cause the list to remain reachable longer than it needs to be.

I guess you could also get into trouble if you have multiple runner threads persisting multiple lists, and the work is arriving faster than you can process it. If that is the problem, then you need to do something to control the rate at which you accept the requests.

Upvotes: 2

Related Questions