Tomcat Excessive Memory Consumption

6,162

---- Edited to provide example as the point isn't coming across ----

A process launches and asks for 1 GB of memory.

That process then starts eight threads (which all have access to the allocated 1 GB of memory).

Someone runs a tool to determine how much memory is being used. The tool works as follows:

  1. Find every scheduleable item (each thread).
  2. See how much memory it can access.
  3. Add that memory together
  4. Report the sum.

The tool will report that the process is using 9 GB of memory, when it is (hopefully) obvious that there are eight spawned threads (and the thread for the original process) all using the same GB of memory.

It's a defect in how some tools report memory; however, it is not an easily fixable defect (as fixing it would require changing the output of some very old (but important) tools). I don't want to be the guy who rewrites top or ps, it would make the OS non-POSIX.

---- Original post follows ---- Some versions of memory reporting tools (like top) mistakenly confuse threads (which all have access to the same memory) with processes. As a result, a tomcat instance that spawns five threads will misreport it's memory consumption by five times.

The only way to make sure is to list out the processes with their memory consumption individually, and then read the memory for one of the threads (that is getting listed like a process). That way you know the true memory consumption of the application. If you rely on tools that do the addition for you, you will overestimate the amount of memory actually used by the number of threads referencing the same shared memory.

I've had boxes with 2 GB of memory (and 1 GB of swap) reporting that ~7GB of memory was in use on a particularly thread heavy application before.

For a better understanding of how memory is reported by many tools, look here. If they python code is parsing the text of one of these tools, or obtaining that data from the same system calls, then it is subject to the same errors in over reporting memory.

Share:
6,162

Related videos on Youtube

Tanner
Author by

Tanner

Updated on September 18, 2022

Comments

  • Tanner
    Tanner over 1 year

    I have a fresh server running Ubuntu 11.04 (Natty) (64-bit). I started off by installing openjdk and tomcat6. When the Tomcat server starts up, it immediately uses 480+ MB of memory. This seems way out of proportion and I'm wondering if anyone has a solution to get Tomcat to use 200-300 MB (or less) memory.

    I used memtop to see this: (Note: I removed all but the large entries. The 499MB entry is Tomcat)

      user@xyz:~# python memtop-0.9.py
      PID |   private/writ. mem |command
          |  current | previous |(truncated)
    19776 | 499.3 MB |    +++++ |/usr/lib/jvm/java-6-openjdk/bin/java-Djava.util.logging.config.file=/var/lib/tomcat6/conf/logging.properties-Djava.awt.headless=true-Xm
    18082 | 148.6 MB |    +++++ |/usr/sbin/mysqld
     1385 |   3.6 MB |    ++    |pythonmemtop-0.9.py
    RAM usage:  ==============================================  69.3 %
    

    Furthermore, you can see what JDK and Tomcat packages I have installed:

    user@xyz:~# dpkg --get-selections | grep jdk
    default-jdk                                     install
    openjdk-6-jdk                                   install
    openjdk-6-jre                                   install
    openjdk-6-jre-headless                          install
    openjdk-6-jre-lib                               install
    
    user@xyz:~# dpkg --get-selections | grep tomcat
    libtomcat6-java                                 install
    tomcat6                                         install
    tomcat6-admin                                   install
    tomcat6-common                                  install
    tomcat6-user                                    install
    

    The startup script for Tomcat sets Xmx to 128M:

    JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
    

    Does anyone have any ideas on what I could do to knock the memory consumption down to something more reasonable? I do not understand why the JVM and Tomcat together would need to consume this much memory.

    EDITS

    For the heck of it, I downloaded Tomcat 6 directly and ran the startup script. Keep in mind that no Xmx value was set this time. When running this, memtop shows that Tomcat is using 737 MB's worth of memory!

    This leads me to believe that there is an issue with openjdk using a serious amount of memory for the JVM.


    I tried the same thing with a fresh .zip download of Tomcat 7 -- same issue. It was using 740 MB of memory.


    I installed the Sun JRE/JDK. Memory consumption dropped to around 400 MB (down from almost 500 MB). This is still more memory usage than what I would prefer!

    (sun-java6-bin, sun-java6-jdk, sun-java6-jre)


    When I run top, I get this:

      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    13749 tomcat6   20   0  481m  68m 9892 S    0  7.4   0:02.85 java
    

    I realize and expect that a 64-bit machine/JVM will use more memory, but I did not expect it to be this high. I'm running on a VM that is only guaranteeing me 512MB.

    • home
      home almost 13 years
      Hm, I'm on 11.04 64-bit as well (laptop only). My Tomcat 7.0.19 starts by allocating approx 50 MB. You did install vanilla tomcat or something like Jetty, GateIn, Liferay, etc.?
    • Admin
      Admin almost 13 years
      Yes, vanilla Tomcat. From what I can tell it should be the most basic, light weight install possible--at least from a package management view point.
    • home
      home almost 13 years
      Did you modify any scripts prior to starting the server?
    • Admin
      Admin almost 13 years
      FYI: I added additional information to my post.
    • home
      home almost 13 years
      Really intersting, maybe you can give Tomcat 7 a try, just to see if it behaves differently: tomcat.apache.org/download-70.cgi
    • Admin
      Admin almost 13 years
      Edited again...
    • home
      home almost 13 years
      Ok, last resort then I'll give up... did you try another JDK?
    • Admin
      Admin almost 13 years
      I have not, but I will gladly try another JDK. Suggestions?
    • HB MAAM
      HB MAAM almost 13 years
      Perhaps the memtop tool just sums all the memory mappings and the likes that's been mapped. Which is going to be a lot, but just because some memory mapping has been made, doesn't mean it's used. What does the RES and VIRT column say if you use top ?
    • Admin
      Admin almost 13 years
      @bmargulies You're probably right. This probably belongs on Server Fault. I posted here because it's my normal "go to", and this is probably the first time my question isn't code related -- That mixed with the fact that when I Googled for a similar problem/solution, I found at least 2-3 other similar posts on StackOverflow. However, their issues/solution were either slightly different or unsolved.
    • HB MAAM
      HB MAAM almost 13 years
      @Tanner So top shows 68M being used. That's not so bad. I'd pay more attention to that number than what memtop says. jvms typically maps a lot of memory - but that's just mappings that might not be used until it's needed.
  • Admin
    Admin almost 13 years
    This might be a possibility, but how can I know for sure? The problem I am running into is that the VM is apparently reporting my memory usage the same as what memtop shows. So according to the hosting company, I am exceeding or about to exceed my memory usage.
  • Edwin Buck
    Edwin Buck almost 13 years
    You told the jvm to not allocate more heap than X; so it won't. Apart from a massive bug in the JVM that only you have noticed, how else would you explain the JVM not honoring it's configuration parameters? Call me jaded, but I think others (including myself) would be in front of Oracle's offices with pitchforks and torches if such obvious (and operational critical) functionality broke.
  • Admin
    Admin almost 13 years
    Yes, I specified the max heap size, but that is not the only memory that the JVM uses. java-espresso.blogspot.com/2011/05/heap-structure-in-jvm.htm‌​l
  • Edwin Buck
    Edwin Buck almost 13 years
    That's true, however, the other items contain so little overhead in comparison to a sizeable heap that you're not in danger of watching your JVM grow to six times the size of the heap (As you are).
  • Admin
    Admin almost 13 years
    So you're saying it sounds like the -Xmx=128M is not being honored?
  • Edwin Buck
    Edwin Buck almost 13 years
    PS, the diagram you referenced showed the internal contents of the heap. That's not the same as the overhead that lies outside of the heap. Your JVM stuffs all of those different spaces into the -Xmx(size) you specified. The only times that -Xmx is ignored is when you use a JVM that doesn't support that extension (all SUN / Oracle JVMs do, and many non-SUN / non-Oracle JVMs support that extension too, but there are a few that don't).
  • Edwin Buck
    Edwin Buck almost 13 years
    @Tanner, I tried to simplify it in a summary (in the original answer) for you. In short, stop blindly trusting your tool's output as true.
  • Tanner
    Tanner almost 13 years
    Thank you for your support. I understand what you're saying about tools not always reporting accurately. However, does it change your mind when I tell you that the server is a VM running under Parallels? The memory reporting features that the hosting company uses apparently reports the same thing. So could it be that they are reporting me as using more memory than what I really am? I'm hosting with MediaTemple. Also, top shows 400+ MB's worth of consumption in the VIRT column, which seems to correspond. Good? Bad?
  • Tanner
    Tanner almost 13 years
    I would go ahead and mark your answer as correct, but to be honest I really don't have this solved. Your answer provides some insight on the issue, but does not lead me to solving it. I'm basically looking for someone who can confirm whether or not what I am seeing is what I should be seeing. From the data I have provided, is Tomcat using too much memory?
  • Edwin Buck
    Edwin Buck almost 13 years
    Tanner, if you can't understand it now, how much more information do you need? Tomcat isn't using too much memory, your tool is over reporting memory. I'd like to explain why, but you're in denial that your tool is over reporting, so it's not possible to talk to you about it until you align yourself with reality. The above explains it in detail, and apparently you haven't read any of it.
  • Tanner
    Tanner almost 13 years
    Please understand where I'm coming from. I'm not in denial. Are you at all familiar with MediaTemple? One of their support techs told me this regarding the "tool":"The script that you can run with the following command on your server will show the private/writable memory (not shared) by each process" -- Here is where I stand: The hosting company tells me I am using over 512MB's of memory (using non-guaranteed burstable memory). You're telling me I can't trust the hosting company's tool. What do I do?