1

I am currently in the process of analyzing code quality for a controller method, that has quiet a few ArrayLists initializations as follows:

public controller(Aggregate agr) {
    List<FCompound> fCompounds = new ArrayList<>();
    List<CCompound> cCompounds = new ArrayList<>();
    List<Dist> oDist = new ArrayList<>();
    List<Trans> oTrans = new ArrayList<>();

    List<CContent> cContents = new ArrayList<>();
    List<FDist> fDidst = new ArrayList<>();
    List<CDist> cDist = new ArrayList<>();
    List<FDist> efDist = new ArrayList<>();
    List<CDist> ecdist = new ArrayList<>();

    List<KList> kList = new ArrayList<>();

which are actually invariable getting assigned to different ArrayList Objects through Lists returned by DB Services

List<FCompound> fCompounds = DBservice().getAllfCompounds();
List<CCompound> cCompounds = DBservice().getAllcCompounds();
List<Dist> oDist = DBservice().getODist();
List<Trans> oTrans = DBservice().getOTrance();

List<CContent> cContents = DBservice().cContent();
List<FDist> fDidst = DBservice().getFDist();
List<CDist> cDist = DBservice().getcDist();
List<FDist> efDist = DBservice().getefDist();
List<CDist> ecdist = DBservice().getecDist();

List<KList> kList = DBservice().getKDist();
}

almost immediately meaning all ArrayList Objects created in the first code snippet are Toast for garbage collection

The issue at first place is that this Controller method is invoked for every request due to a poor design of the 1 monolithic controller which serves 100% of the application traffic, now I am starting to doubt if this is gonna start causing Memory leaks due to less heap space?

What would be a workaround for this problem, would initializing the lists with null as

        List<FCompound> fCompounds = null;

or it wouldn't change anything?

is there a way to analyze the heap space through a stress test for this method?

Anirudh
  • 2,286
  • 4
  • 38
  • 64
  • "*... start causing Memory leaks due to less heap space?*" - This is not really a memory leak. [You have to put in some effort to create a real memory leak](https://stackoverflow.com/questions/6470651/how-to-create-a-memory-leak-in-java). Does the customer actually have memory- or performance problem? If not, don't try to fix problems that re not there (["*premature optimization is the root of all evil*" -- Donald Ervin Knuth: *Computer Programming as an Art* (1974), p. 671](https://dl.acm.org/ft_gateway.cfm?id=361612&ftid=289767)). – Turing85 Jan 18 '20 at 08:58
  • @Turing85 So wait for my application to crash first? And then firefight? I am seeking a way to do a memory stress test through a tool quickly. – Anirudh Jan 18 '20 at 09:02
  • It's a web app? If so, use a tool like [Gatling](https://gatling.io/), stress test your app. If the app should indeed crash, then analyze the root cause. But I would not start with the analysis. – Turing85 Jan 18 '20 at 09:06
  • Its an event driven micro service. – Anirudh Jan 18 '20 at 09:16
  • 1
    What technology do you use for the events? Gattling has native JMS support and there are 3rd party plugins for Kafka. One can also use JMeter to stress test JMS services. – Turing85 Jan 18 '20 at 09:21
  • Kafka, Spring boot and Postgre SQL DB. – Anirudh Jan 18 '20 at 09:23

1 Answers1

0

For analysing heap space, you can use visualvm. Till Java 8, it was provided with Oracle JDK8. Starting with JDK 9, Visual VM will not be included with Oracle JDK. You can get it from https://visualvm.github.io/download.html.

For your first question, memory leak will not happen due to less heap space. Whenever you are creating object and it is not referenced any more then it will be eligible for garbage collection. In your controller, it has few array initialisation for e.g.

List<FCompound> fCompounds = new ArrayList<>();

Now, when below line gets executed, above arrayList object is eligible for garbage collection.

List<FCompound> fCompounds = DBservice().getAllfCompounds();

According to my knowledge, these objects not even survive first garbage collection and destroyed when garbage collection for eden space gets executed. So no worries. Even you can check the same using above tool I mentioned.

You can even intialize arraylist as null.

List<FCompound> fCompounds = null;

But, in this case if your DB service return null(I don't know how your DB service has been implemented) then you can get NullPointerException. So to use this and get rid of NPE, you can make use of java.util.Optional while returning anything from DB service.

Joy
  • 394
  • 2
  • 9
  • Can DB services really return null? The are simple calls to spring data boilerplate code like _repo.finaAll()_ etc – Anirudh Jan 19 '20 at 06:42
  • 1
    Anirudh you can initialize all of your lists in controller with null value but make sure you should't get NPE in case of DB service returns null value. Have proper null check that's it. Even you can use optional as suggested. I hope you understand. – Joy Jan 19 '20 at 11:42