Java memory behavior: different with Thread.sleep

I am trying to do memory analysis with visualvm. I wrote basic code that runs an infinite loop to add objects to the list.

package home.always.learning.java; import java.util.ArrayList; import java.util.List; public class Heaper { private static List<PersonDetails> listObj = new ArrayList<PersonDetails>(); private static final String nameConst = "Tarun Trehan"; public static void main(String[] args)throws Exception{ personListCreation(); } public static void personListCreation() throws Exception { int i = 0; while(true) { System.out.println("Looping to create person list..."); i++; listObj.add(new PersonDetails(nameConst+i)); //Thread.sleep(1000L); } } } 

As expected, the memory is triggered and visible in visualvm. 1st snapshot attached, i.e. Memory_Shoots.JPG .

However, if I remove the following comment from the code and allow the program to sleep for 1 second; the result is different:

 Thread.sleep(1000L); 

Memory increases, but then stabilizes and continues. Please refer to the second snapshot attached ie Memory_Stabilizes.JPG

I can not understand this behavior? Can you submit your materials.

Memory_shoots

Memory_stabilizes

+4
source share
2 answers

After looking at a slightly modified version of the code (a fixed number of iterations, adding a pause of 5 seconds after starting, so that my IDE can connect to visualvm, deleted system.out.print for speed, etc.), it seems that your culprit is garbage collection:

With a 100-day sleep: (run after 5:18) garbage collection with sleepgarbage collection with sleep

With a 10-day sleep: (for 5:01) garbage collection with sleepgarbage collection with sleep

With loss of 2L: (for 4:57) garbage collection with sleepgarbage collection with sleep

With 1 L of sleep: (run for 6:36) garbage collection with sleepgarbage collection with sleep

With 0L sleep: (ran 0:23) garbage collection with sleepgarbage collection with sleep

Thus, basically, we find that the heap used will grow slowly until the Eden space is full (which will result in a distribution failure), moving the older eden members (almost all of them looking at space usage) to survive 0 / 1, and some of them are in the old gene. The difference between sleep and lack of sleep may well be the difference between the relative frequencies of the secondary collections and the main collections.

+3
source

There are a few things to consider:

  • How big are these PersonDetail objects?
  • How much memory is required to create a PersonDetail object that is not part of the object?

This second value can be very much. A list of arrays will cause garbage every so often. The process of creating the string "nameConst + i" will result in some garbage objects.

Suppose the answer is that PersonDetail is small, but it takes an average amount of memory to create it. Then the JVM will have a bunch of garbage to throw away (garbage collection) for every PersonDetail you create. When you create PersonDetails, garbage will accumulate and eventually the JVM will collect it. At the stage of garbage collection, a lot of free memory will be detected, since most of the allocations are short-lived objects. This can cause the graph to look like the one shown in the second image, a saw blade that uses memory, after which a lot of garbage is collected.

Now imagine that you are quickly creating a bunch of objects (without a sleep instruction). Now the total used memory will grow rapidly both through garbage and through objects that you keep in the list. When you get to maximum memory, garbage collection will occur more often. View as the top graph.

I'm not sure if this is what happens, but one thing you can do to look at it is to look at the selection in VisualVM and see how many objects are created by the class, and more importantly, how much memory they take Compare the amount used by PersonDetails with other material that is simply cleaned up when needed.

+2
source

Source: https://habr.com/ru/post/1486743/


All Articles