1

My website is a SpringBoot application deployed in Linux server. I add JMX so that I can monitor this website by JVisualVM. I run it as below:

nohup java -Djava.rmi.server.hostname=10.25.161.45 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=22222 -jar sms-web.jar &

I start load test and I can see that the memory consume is escalating very fast, as the red rectangle shows here. This is understandable because there are a lot of TCP connections establised and disposed while in load test. But after the load test is done, it still continues to consume a lot of memeory, sometimes to 800MB, as you can see in the green rectangle. What happens under the cover? Why it consums so much memory?

Edit: Is there any way for JVM to do a through GC to release a lot of memory?

enter image description here

Robin Sun
  • 1,352
  • 3
  • 20
  • 45

1 Answers1

1

This is quite normal behaviour for any Java application. As long as your application is running, objects will be created, even when it's not being used (threadpools being checked/refreshed, ...).

That means that it's only normal that heap memory goes up over time. However, when necessary, the garbage collector will run, and will destroy any objects that are no longer in use. That's why you can see a clear memory usage drop at certain times.

Now, the garbage collector will only run when necessary. This process often happens when your memory in use (blue line) is getting close to the memory that is allowed to be used (orange line).

This explains two things:

  1. It explains the zigzag lines during your loadtest, which means many objects were being created and being destroyed afterwards by the garbage collector.
  2. It explains why your application can use more than 800MB of memory before freeing anything, because there was still more memory it allowed to be consumed.

Now, if you think it's problematic that your application allows about 1GB (or more) memory to be consumed, you'll have to play around with your JVM settings, and perhaps reduce the -Xmx parameter to a reasonable amount. Make sure to run some loadtests afterwards, to see how your application behaves when reducing the maximum allowed memory, as it could have a higher impact on the performance of your application since the garbage collector would have to run more often.

g00glen00b
  • 41,995
  • 13
  • 95
  • 133
  • Hi @g00glen00b, thanks for you effort. It is much more clear. I still have one concern. If the website is not being used, and its memory consuming is around 100M, then I feel confident if there are 100000 requests coming in later. But if the website is not being used with memory consuming around 800M, then is it OK for later huge web requests? – Robin Sun Nov 07 '18 at 03:10
  • Besides, I userstand that objects will be created while no one uses the website. But why is it using up to 800M? I find that if I restart the website and don't perform any load test, I see that the memory consume is always around 50M up and down, much less that 800M. So I guess, the load test did something affecting this. – Robin Sun Nov 07 '18 at 03:11
  • @RobinSun Sure, if it would have consumed 800M and you make huge web requests later on, the garbage collector would kick in pretty soon, and free up enough memory. – g00glen00b Nov 07 '18 at 06:34
  • @RobinSun The loadtest triggered the garbage collector quite often, and additionally to that, the maximum amount of memory was increased, causing the application to be able to reserve a lot more memory. However, as mentioned in my answer, you can configure the maximum allowed heap memory your application is able to use by using `-Xmx`. The default value is determined by the JVM, but could go to 1GB, even when your application doesn't really need it. – g00glen00b Nov 07 '18 at 06:37
  • @RobinSun But to be really sure if there's no memory leak, you should run your application even longer to see if the memory after a GC stays around the same value, or increases. – g00glen00b Nov 07 '18 at 06:40
  • really glad that we can have such detail talk. I know that -Xmx can set the max memory limit for JVM. But I want to know why the memory could go to 1GB even when the application doesn't need it? Maybe I can ask the question in this way. While it is during load test, the memory consume runs up to 1GB. Once the load test is done, why doesn't it free 900MB and only keep 100MB in use, because now the max memory limit is still 1GB, then it will not trigger GC frequently. – Robin Sun Nov 07 '18 at 07:26
  • @RobinSun Well, the JVM does occasionally reduce the heap size, but not as often as far as I'm aware. You can tune that behaviour though, as you can read in [this question](https://stackoverflow.com/questions/4952568/is-there-a-way-to-lower-java-heap-when-not-in-use). However, in your case I would just start with setting `-Xmx` to somewhere between 300 and 500MB. – g00glen00b Nov 07 '18 at 07:54