I can confirm that a Web application I am working on (Jetty, Struts2, JDBC) consumes about 300 MBs more RAM (1.2G) right after startup when running in JRE 1.8.0_72 compared to JRE 1.7.0_80. The application is running on Centos 6 x64 and to make the memory measurement as transparent as possible I have disabled swap and set -Xms equal to -Xmx (40% of available RAM). I have used dstat --top-mem or top -m to get the total memory consumed by the java process.

Moreover when Web clients are connecting too often to the application, the total consumed memory rises until the system gets out of memory and kills the java process. The only what I can see is an information in /var/log/messages:

Nov 10 21:29:54 my kernel: Out of memory: Kill process 26610 (java) score 570 or sacrifice child

When I run an infinite loop from bash that invokes 4 parallel Web clients that connect to the application (= establish new TCP connection), request the application status and disconnect then the total memory consumed by the application rises about 100-200 KBs each minute. Each client does 6-10 requests per minute. Used heap memory size is stable.


In the way question is asked

why Java 8 allocating too much memory on my machine

I don't think anyone will be able to answer, however there are several guidelines which might help. Given that you are measuring memory via task manager you are interested in total RSS used. So

  • Step 1: Compare JVM defaults between version you are running. You can get them using java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version command for both jdks. Using text sort on top of output you'll be able to get a nice diff using any compare tool. Things like changing default GC collector and thread stack size will affect final RSS a lot.
  • Step 2: Measure allocation for each memory pool. In general total memory used by java could be calculated using heap + metasize + code cache + native + (thread_stack_size * maximum_number_of_threads)
    • Heap memory easy measurable (and could be easy compared!!) by mature tools (Eclipse Memory Analyzer, VisualVM, etc.). If you memory increase in heap area -you are very lucky. In additional visual vm allow you to install plugin which will show values of all memory pools accessible via jmx.
    • metasize (aka permgen in jdk<8) should more/less equal and could be found with jmap tool. No need to play with flag, you can get number and just compare whenever it's increased or not.
    • Code cache: in addition to reserved code cache there you can set initial code cache (and that will affect how much RSS is used).
    • native: it's a bit of black sheep. If all other memory pools are equal (your memory bump is 2GB) memory lost must be somewhere in native area. The only tool I'm aware of is jcmd and it has extensive documentation in oracle docs.

Non technical - whilst tweaking various options in order to reduce memory can help, the chances of getting right values are close to finding needle in haystack. I would really recommend to have a about how RSS is used in java. This knowledge will be handy for quite a few years!

Please let me know whenever you'd like more concrete references or better explanation. And... good luck with your quest ;-)

Related Query

More Query from same tag