Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
×
Programming Software IT Linux Technology

Understanding Memory Usage On Linux 248

Percy_Blakeney writes "Have you ever wondered why a simple text editor on Linux can use dozens of megabytes of memory? A recent blog posting explains how the output of the ps tool is misleading and how you can get a better idea of how much memory a process really uses."
This discussion has been archived. No new comments can be posted.

Understanding Memory Usage On Linux

Comments Filter:
  • by pontus ( 135914 ) on Monday February 06, 2006 @09:09AM (#14649985)
    Nice article.
    It could also have mentioned mappings on /dev. For example, the X server, on a system with a 256MB graphics adapter, will map all that memory into its address space, making X look huge, even though it's not using all that much system RAM. This will show up as a device-backed mapping in the maps file.
    On a related note, X also looks big because it's holding pixmaps belonging to various applications (Firefox comes to mind).
    • Nice article, indeed. It didn't tell me what I'd hoped it would, though, that there is a tool to give me memory stats the way Data General's AOS/VS II tools did. In the DG world, one component of process memory organization mapped a process' space into four areas: shared code, unshared code, shared data, and unshared data. The DG equivalent of "ps" reported shared memory and unshared memory, and it made short work of determining which processes were pigs and which weren't. I haven't found that in either
      • by ratboy666 ( 104074 ) <fred_weigel@[ ]mail.com ['hot' in gap]> on Monday February 06, 2006 @12:52PM (#14651426) Journal
        The "problem" is the concept of a COW page (copy on write). Coupled with the semantics of mmap().

        In a nutshell: I can use mmap() to map /dev/zero into memory, for (pretty much) as big as I want. 200MB? Its now mine.

        I can have a pointer to this memory.

        The problem? The memory doesn't exist. What I have is a pointer, and a guarantee that enough backing store exists to satisfy it.

        If I read through that pointer, I will see zeros. It *is* /dev/zero after all. However, I can write into the memory. If I write something, the page that is changed is copied and replaced; taking memory AT THAT TIME. Sparsely.

        The mmap() call can map a file (backing store) and allow data to be shared. Memory does not need to be used until the data is read (or written). And this time, the backing store doesn't even need swap (because the file is the backing store).

        All of which means non-changeable may be altered. Changeable may be non-existent or shared. Try to teach that to your DG tools.

        A page of code that is shared - may becomes a page of code that is private. A page of data that is unwritten doesn't have to exist. Even if it is read! A page of data that is written may STILL be shared.

        "ps" and the other tools could walk through typical process maps, counting up pages, and figuring out what each was for, but that may be a bit too intensive. The pages aren't "cross referenced" for that purpose. Besides, the page could be COWd, and then swapped. Should THAT count against the memory of the application? Maybe, maybe not.

        So "ps" by default gives you an idea of the "big picture" for each process.

        Ratboy
  • by Anonymous Coward on Monday February 06, 2006 @09:10AM (#14649988)
    How can they diminish EMACS like that ?
  • by 0xABADC0DA ( 867955 ) on Monday February 06, 2006 @09:12AM (#14649997)
    Try statically linking a program that uses just a few glibc calls and it's pushing 800k. Now add in libc++, Qt/gtk, Xlib, kde, boost, xml, etc and you're talking a lot of memory. This is what gets me about people who say "well Java performs okay now, but it uses so much memory".

    A typical C/C++ based app uses just as much memory, it's just shared between processes. And for that matter, startup time of the first thing using kde/gnome isn't all that great either. Isn't it about time some effort was put into making Java or Mono part of the system, so it can be shared like C apps do?
    • A typical C/C++ based app uses just as much memory, it's just shared between processes...

      That's the point. Nobody cares about how much actual memory a C/C++ app touches.

      Making Java "part of the system" won't help much either because the libraries aren't the same. You could argue that at the bottom of the pyramid its still libc that's being used, but we still have and need all the wrappers on top of the library to make it compatible with Java code.

      So until people find it normal to run more than one o

    • by CyricZ ( 887944 ) on Monday February 06, 2006 @09:33AM (#14650075)
      What do you mean, making it "part of the system"? Are you suggesting that they be embedded within the Linux or BSD kernels, for instance? I would hope not, because for serious use that is a recipe for disaster.

      Part of the problem with Java is that each VM has traditionally had its own copy of the Java class library. When you consider how huge the standard library is these days for Java, it's no wonder that even a small Java program consumes so much memory. And running several programs, each duplicating data from the others, is wasteful.

      Apple has had for years a JVM that shares classes between numerous virtual machine instances. It thus reduces unnecessary memory consumption.

      • Apple has had for years a JVM that shares classes between numerous virtual machine instances. It thus reduces unnecessary memory consumption.

        So it's kind of like a slow version of native compiled code from gcj?
    • by Max Threshold ( 540114 ) on Monday February 06, 2006 @09:33AM (#14650079)
      The problem is that the bulk of Java's libraries aren't shared. At least, that's how it looks to pmap.

      Sun JVM running a simple "Hello World" program that sleeps 1000ms between messages in an endless loop:

      mapped: 260888K writeable/private: 199604K shared: 54652K

      It wouldn't be hard to create a launcher that would run them all on the same virtual machine. Such a launcher would a candidate for the system integration you suggest. After all, if you needed to run Windows apps on your Linux box, you wouldn't run multiple instances of VMWare, would you?
      • by swillden ( 191260 ) <shawn-ds@willden.org> on Monday February 06, 2006 @10:33AM (#14650409) Journal

        The problem is that the bulk of Java's libraries aren't shared. At least, that's how it looks to pmap.

        There's clearly something pmap is missing. I just tried exactly what you said, and on my system, pmap reports:

        mapped: 209820K writeable/private: 169696K shared: 33660K

        So then I ran 200 copies. pmap reports the same stats for each of them, but that's clearly absurd. 170MB writable/private multiplied by 200 instances is 34GB of RAM. But my laptop has 2GB of RAM, only 136KB of swap is being used, and 800MB of my RAM is being used for cache. So those 200 java instances, plus everything else I have running at the moment (which is quite a bit), are consuming about 1.2GB of RAM. That's quite a bit, but nothing like what pmap would lead me to believe.

        Thinking about it, I think I can see what's going on. pmap is showing the mapped size of each process. Each JVM individually mmaps a huge amount of memory, because it maps in all of the Java libraries. However, mmapped pages don't consume any virtual memory unless they're actually used. This trivial program only uses a tiny portion of the libraries, so only a very small part of the mapped pages is actually read. Each JVM also mmaps a big block of anonymous memory for use as its heap but, again, the mapped address space doesn't consume RAM/swap if it's never touched, and this trivial app doesn't use much heap.

        My conclusion: pmap *also* overestimates memory usage, because some portion of the mapped address space isn't actually in use. RSS, on the other hand, only measures memory that is actually in use, but doesn't distinguish between memory that is shared and memory that is not. VSZ is the most pessimistic measure, since it includes all mapped memory, shared and unshared.

        Looking again at my 200 Java processes confirms this. Each has an RSS of 6.7MB, which is too much to be "correct" (in the sense that 200*6.7MB is more RAM than my whole system is using), but not much too much, which tells me that a lot of that 6.7MB RSS is unshared.

        Looking at the pmap output in more detail, I see that most of the memory is mapped in three big anon blocks -- probably the heaps used by the generational garbage collector. The libraries are smaller and they're (duh) read-only which I'm pretty sure means the libs *are* shared across multiple instances of the JVM, because I believe that multiple processes that mmap the same file in read-only mode only get a single shared copy.

        That means the bulk of the actual memory usage is writable, not libraries, and it's all unused heap space. Assuming the generational GC does the obvious thing and unmaps the whole "dead" generation block, the bulk of the heap space will usually be unused... and the JVM actually will "give back" heap that it no longer needs, at least in part. RSS should show that. Hmm... how to construct a test case to verify it...

        Bottom line, I think: Java apps do use a little more actual memory than C/C++ apps, and trivial Java apps do use a lot more actual memory than trivial C/C++ apps, but it's not nearly as bad as pmap shows because the GC will always have a lot of extra memory mapped that has never been touched (assuming it does unmap and remap the dead generation, and it would be stupid not to).

        Enough of my rambling, semi-informed speculation. Anyone who knows more about how this stuff works, please weigh in and correct me.

        • That is how it should be read I think. To start 200 instances of your Java proggie you pretty much did the same thing as starting 200 threads in single virtual machine. These threads show in ps output as operating system processes and they map entire address space of virtual machine which is why their sizes are identical.

          Memory usage of Java actually scales very nicely with silly number of threads. A couple of months ago I created a small server which opened lots of listener sockets in their own threads.

          Wit
    • A typical C/C++ based app uses just as much memory, it's just shared between processes [emphasis mine -mi].
      Well, is not this the whole point, eh?
    • Isn't it about time some effort was put into making Java or Mono part of the system, so it can be shared like C apps do?

      Huge effort required, with some hard design decisions looming ahead. Jar files store java bytecode, which is (usually) jit-compiled at runtime to native code by the VM. My guess is that sharing the bytecode alone isn't enough and probably happens already (A disk page read by several different processes is loaded into 1 physical memory page which is then mmap'ped by the OS to the processes

      • I agree completely, although an alternative solution is to put the JVM into the kernel, where it could manage different user-level processes that all shared the same optimized code (essentially a process would hold the native code a Java app uses, if any). Of course, this would mean at least some optimizations would be global across all Java-using programs. That isn't necessarily bad though. Apple does this somewhat in userland with their version, but it still has a lot of unshared code that could be sha
    • Comment removed based on user account deletion
    • Well, libraries are shared, sure. But libraries can be bloated.

      I mean, it's nice that people explains that all that memory that processes use is shared between processes, but the linux desktop platform couplement (kernel libc Xorg qt libkde app) is far from being perfect. Just take a look at the upcoming gnome 2.6.14: Too many performance improvements in the sahred libraries, right? [gnome.org]
      • What gets me is how some distro builders see a security warning about setuid/setgid binaries using lazy so loading, and decide that using -Wl,-z,now is a good thing to add. Excuse me, but that will pull in EVERY library at link time, whether used or not, often leading to some MAJOR bloat.
        Yes, it "fixes" the "problem", but so would using rpath to DSOs not writable by users or ensuring that LD_LIBRARY_PATH doesn't point to user writable directories. Without the load time bloat.

        Regards,
        --
        *Art
    • This is what gets me about people who say "well Java performs okay now, but it uses so much memory".

      But python, for example, is in the situation. But, it doesn't use so much memory, because it does the right thing and wraps the system libs for such things, instead of reimplementing everything.

      A typical C/C++ based app uses just as much memory, it's just shared between processes.

      But processes from many languages use these same libraries.

      Isn't it about time some effort was put into making Java or Mono par

    • A typical C/C++ based app uses just as much memory, it's just shared between processes. And for that matter, startup time of the first thing using kde/gnome isn't all that great either. Isn't it about time some effort was put into making Java or Mono part of the system, so it can be shared like C apps do?

      A virtual machine is a virtual machine. There's nothing whatever to stop you running multiple Java threads running different applications in the same virtual machine - this is, after all, exactly what a

  • man page update (Score:5, Insightful)

    by suso ( 153703 ) * on Monday February 06, 2006 @09:18AM (#14650020) Journal
    How about going one step further than just blogging about it and actually submitting a documentation update to the ps man page. That way future confusion of the ps output could be avoided. Of course I guess people have to actually read the man page (In honor of slashdot, I didn't read it before posting this comment ;-)
    • Re:man page update (Score:4, Informative)

      by TallMatthew ( 919136 ) on Monday February 06, 2006 @12:28PM (#14651241)
      How about going one step further than just blogging about it and actually submitting a documentation update to the ps man page. That way future confusion of the ps output could be avoided.

      Because what ps reports is the truth, from a certain point of view.

  • Emacs (Score:2, Funny)

    by Touisteur ( 857728 )
    If you wanna see a real OS with memory hogs, run Emacs...
    • Emacs gets flack for memory usage based on using a whole couple megs of memory back in the day -- but do you want to compare its usage to Visual Studio's or Visual Slickedit's?

      BBedit might use less memory -- haven't been following BBedit recently...
  • Linux (and to be fair, Unix-like systems in general) shine at file & memory management. Many people don't know, but executable files are not 'loaded' in the Windows sense - they're just mapped into memory. This design improves performance and gives the system better performance under swapping (not thrashing, mind you). Things like mem mapped files are integral in the way the system is designed and implemented. That's one of the very reasons why a Linux machine usually runs faster and more reliable than
    • by Anonymous Coward on Monday February 06, 2006 @09:37AM (#14650103)
      Many people don't know, but executable files are not 'loaded' in the Windows sense - they're just mapped into memory.

      Apparently, some people don't know that modern NT-based Windows versions also behave in exactly the same manner.

      • Well, but with Vista this advantage will be gone again, and .Net bytecode will be translated, although all it will ever run on is x86 systems. And on top of that you need the whole .Net framework and everything else. I always ask myself how an operating system with zero apps can take up several GB of space. Maybe it's because a Windows Graphics driver package of NVidia or ATI is as big as the whole kernel source code, where all all hardware support is implemented in.
        • Not completely true. They (MS) have actually detailed the scenarios that enable (marketspeak on) shared pages, and those that do not. The bottom line is that common libraries in the global assembly cache will almost always stay shared, and you can make sure that your own assemblies do, too, if you do not mess up the settings.

          This is somewhat similar to the fact that you can't share a relocated module between processes in the "native" world. If you customize the loading of an assembly too much, the actual p

          • Oh, I wasn't referring to the sharing part. I was referring to the "just mem-mapping into memory" part. That certainly won't work with bytecode and is the very reason Java and .Net applications always take so long to load.

            The sharing is is for sure. Java shares all the classes in one VM instance, and old dlls are also shared. The problem with Windows is just that they have even less discipline (and means) in organizing their files, libraries and executebales, in short:ressources than the Unix world. So it's
      • Under Windows, for various reasons (including the lack of a sane update and library dependency management system), applications all have their own damn copies of all the shared libraries. Which means that memory doesn't get "shared", as it does under Linux. It just gets wasted.
    • Comment removed based on user account deletion
      • by JesseMcDonald ( 536341 ) on Monday February 06, 2006 @10:25AM (#14650375) Homepage
        Actually, modern runtime linkers use a table of offsets rather than embedding the relocated symbol addresses directly into the executable code, and the relocations themselves are handled by mapping the file contents into virtual memory at the necessary addresses. With those two techniques combined, it is almost never necessary for the in-memory version of the executable to differ from its on-disk representation where the code and constant-data sections are concerned. When a typical application begins execution, nearly all of its virtual memory will be mapped directly onto the executable file and its shared libraries, and loaded on demand. The initialized-data section must be copied into virtual memory, and the uninitialized-data section and the stack are typically allocated as they are accessed on a page-by-page basis. Aside from a handful of housekeeping data for the linker and the C libraries, the rest of the virtual memory consists of read-only memory-mapped files.
    • by Anonymous Coward
      Please do yourself a favor and educate yourself before making any future bogus claims.

      The following two articles respectively deal with executable and libary loading in Windows:
      http://msdn.microsoft.com/msdnmag/issues/02/02/PE/ [microsoft.com]
      http://msdn.microsoft.com/msdnmag/issues/02/03/Loa der/ [microsoft.com]
  • by volts ( 515080 ) on Monday February 06, 2006 @09:27AM (#14650052) Homepage
    Devin's blog also has an excellent posting on Apache performance. "Tuning Apache, part 1" (and the comments) is the sort of succinct empirical advice it is always nice to find.
    • by a16 ( 783096 )
      I just wanted to add my confirmation that the Apache article is an excellent tip.

      I had been experiencing issues reaching the max clients on a busy apache server serving around 6mbit/sec of images at peak times, and had been forced to increase the maximum child process setting to a very large number to cope with the peak daily periods.

      Having just made the changes recommended in that article, ie. changing the keep alive timeout to around 2 seconds rather than the default of 15 - we've gone from an average of
  • by soboroff ( 91667 ) on Monday February 06, 2006 @09:39AM (#14650111)
    All those shared libraries are also part of the reason that KDE and GNOME can take so long to start up, and why more memory and a higher-RPM hard disk can speed things up. It does make me laugh sometimes that Emacs is now one of Linux's fastest-starting desktop apps.
  • by twitter ( 104583 ) on Monday February 06, 2006 @09:51AM (#14650172) Homepage Journal
    Using the pmap -d trick gives some insight but the amount of swap space used is what actually slows down system response. The author notes that a user who mostly runs either KDE or Gnome will pay a greater marginal cost for running the one Gnome or KDE application that's different. That's true, but it's also hard to avoid and it often does not matter, even on a modest system with 256 MB RAM. You would think that running konqueror, kontact, gimp and gnumeric on Enlightenment or Window Maker would suck down resources. It does, but it might not be enough to get you into swap space. Just run top and see. A low resource window manager can use fewer resources than a full Gnome or KDE Window Manager, despite the magic of shared libraries. DSL and Feather GNU Linux distributions run on P1s because they come with very low resource programs, which may or may not share many libraries. A little swap use does not hurt, but things get slow when too much gets in there.

    The whole discussion should be grounded in the reality of alternatives. A typical M$ system will grind it's way into swap space on start up, before the user loads anything! The very latest and greatest Linux distros run well on Pentium IIs and the like, which XP refuses to install on.

    • You're likely talking about differences between OS's various VM systems. I'm not sure which way is best, but here are some observations I've made . .

      Solaris will go to swap very early on, likely swapping inactive pages, even if there is plenty of physical memory to be had.

      FreeBSD doesn't seem to go to swap until it damn near runs out of physical memory to use.

      Linux is somewhere in between the two. It doesn't go to swap quite as early as Solaris, and also not as late as FreeBSD.

      Which way is best? Not sure
    • I run a P2, 266 at home, with 256 MB of RAM. KDE 3.4 runs pretty slow. I've turned off a lot of the eye candy, but still the response time is quite slow. Windows 2000 on the other hand is quite speedy, I can't speak for windows XP, because I don't run it. The problem is, is that this isn't really a fair comparison, as the Windows 2000 UI, it more comparable to something like sawfish. Well, the look is similar, but Even straight X Windows has a better feature set. So, I could use Sawfish, but If I star
    • You would think that running konqueror, kontact, gimp and gnumeric on Enlightenment or Window Maker would suck down resources. It does, but it might not be enough to get you into swap space. Just run top and see.

      I find it quite ridiculous that logging into Windows XP -- which has very few programs installed on it, basically AV + some games -- causes my pagefile to start grinding, while I can run many instances of Konqueror, KDevelop, OpenOffice.org and watch a DVD and listen to music all at the same ti

  • by cciRRus ( 889392 ) on Monday February 06, 2006 @10:09AM (#14650281)
    What I really wanna understand is the memory usage in Windows.
  • Overdue (Score:5, Interesting)

    by Chris Pimlott ( 16212 ) on Monday February 06, 2006 @10:09AM (#14650285)

    A nice article, been looking for more information on this. So often you read items in program FAQs or such giving a disclaimer on how ps memory usage is misleading, but they offer no better way. Okay, so ps memory usage information is pratically useless; now what am I supposed to use?

    I was hoping for a bit more, though; like, say, a small program that lets you see both the aggregate virtual memory total as well as the memory used specifically by the program. Add a few options for how to handle the only-one-app-using-a-library situation. Doesn't seem like it'd be that hard, and very useful.
  • Sure (Score:3, Funny)

    by arvindn ( 542080 ) on Monday February 06, 2006 @11:06AM (#14650620) Homepage Journal
    "Have you ever wondered why a simple text editor on Linux can use dozens of megabytes of memory? "

    Of course. EMACS - eight megabytes and constantly swapping.

    • In the days when I was first involved in setting-up Unix systems (when SUN 3s were the fancy new toy), 8MB was a huge deal on a system with 4MB RAM. Thus we essentially banned emacs and stuck to vi. Now my thought would be "only 8MB, whats the worry".
      But has emacs also had feature creep since then, with corresponding memory growth?

      Worrying too much about effeciency (memory or processor) can be bad. Failing to keep it at least in the back of your mind while designing and coding leads to some of the awful per
  • by AtariDatacenter ( 31657 ) on Monday February 06, 2006 @11:12AM (#14650654)
    Because there is nothing quite like seeing you've got 20 Oracle instances at 1gb each on a 4gb box. :)
  • Memory Management (Score:4, Informative)

    by johnnyb ( 4816 ) <jonathan@bartlettpublishing.com> on Monday February 06, 2006 @11:14AM (#14650671) Homepage
    On a related note, if anyone is curious how memory management library calls such as "malloc" work, you might check out my article on the subject [ibm.com].
  • by egarland ( 120202 ) on Monday February 06, 2006 @11:14AM (#14650672)
    The architecture of Java doesn't allow it to share library memory space like this. The effect of this is Java programs, appear to use about the same amount of memory as compiled programs when, in fact, they are using quite a bit more. This is why running a Java program that takes up 25 megs of memory can seem to suck the life out of a computer while a compiled executable using 25 megs doesn't. Java is probably really using about 10x more memory.

    It's also why systems running a Java framework with multiple programs executing in the same Java process do so much better than ones where everything is in its own process. This is Java's sweet spot, where these JVM architecture disatvantages have the least impact.

    This is my understanding of how Java's libraries work. Someone let me know if I'm missing something here.
  • top (Score:5, Informative)

    by Kupek ( 75469 ) on Monday February 06, 2006 @11:18AM (#14650688)
    Run top. Check out the column that says SHR. Subtract it from VIRT if you want to know the virtual memory usage of a process excluding shared libraries, or subtract it from RES if you want to know the physical memory usage of a process excluding shared libraries. Problem solved.

    I don't like how he phrases that what ps reports is "wrong." It's not wrong, or even "wrong." It reports exactly what Linux tells it (through the proc filesystem). It's just might not be what you expect it to be, which means you don't understand the tools and the system. When ps reports that a process' virtual memory usage is xKb, that is correct. In the address space for the process, xKb have been allocated. Shared or not, they're still in the address space.
    • mod parent Overrated (Score:3, Informative)

      by Darkforge ( 28199 )
      That's just not true, as someone else has swillden points out in this comment to the current story [slashdot.org]. Nobody should follow your suggestion.

      Based on your over-simplified claim (which I'll call "wrong") the 43 java threads on my Tomcat box are using 3.0GB of RAM total, minus 426MB shared, which is impossible on a box with 256MB of RAM and 512MB swap.

      More generally, the problem with ps (and top) is that they fail to highlight the most important piece of information: the amount of unshared memory each process is
  • by Colin Smith ( 2679 ) on Monday February 06, 2006 @11:19AM (#14650692)
    The first person to use a system might load 128Mb worth of libraries and applications. The second and all subsequent users may only use 15-30Mb worth of RAM for each additional user. e.g. A 1Gb RAM system could handle 30 concurrent users rather than 8.

     
  • by dzfoo ( 772245 ) on Monday February 06, 2006 @11:22AM (#14650725)
    >> Have you ever wondered why a simple text editor on Linux can use dozens of megabytes of memory?

    Correct me if I'm wrong but... doesn't the fact that KEdit uses a lot of libraries that consume resources and impact system performance -- whether shared or not -- still means that it is a hog? I mean, if a seemingly simple application is consuming "dozens of megabytes of memory", saying "oh, it's OK, because most of it is being shared and already commited", does not really excuse it. What if those libraries are not currently being used by any other process?

    In order for the shared memory to lessen the impact on the system, the user must be running some other processes that share the same libraries. This to me is a *BIG*, and unwarranted, assumption by the developer, as evidenced by his example of someone running the Gnome environment but running a single KDE application.

          -dZ.
  • The article is factually correct. Ps does include shared libraries in its size, so the incremental amount of memory used by an application may well be much less than the total of its memory footprint -- assuming that the shared libraries are already loaded by some other application.

    However, this still does not excuse a text editor for having a 25MB footprint!

    When that editor runs it WILL require 25MB of memory to run (well, the working set may be a little smaller, but if we don't want any paging we need

    • I'm sorry, but I couldn't care less if my text editor consumes 25 MB of memory (shared or otherwise). 25 MB is peanuts, and I'll gladly use such an editor if it suits my needs, provides a snappy and clean interface and its base foot print doesn't increase when editing larger files.

      Unfortunately, for most GTK Linux apps at the moment (some of which I cannot live without), the "snappy" part isn't true because (so I'm told) GTK doesn't make proper use of graphics card acceleration. I'd glady use application

      • Maybe you don't care on your 1-user system.

        But if everyone thought the way you did, and say, you had a limited pool of generic compute servers that hundreds of you had to share, and everyone wanted to load their pet tools and eat up all the RAM rather than using the IT standard-build suite, I bet you'd have a completely different attitude.

"No matter where you go, there you are..." -- Buckaroo Banzai

Working...