• Post Reply Bookmark Topic Watch Topic
  • New Topic

Linux: Multiple identical JAR files in Java process  RSS feed

 
Ben Rowland
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,


I have a problem here that I can't get my head around. I'm running a Java program on Linux (SuSE 9.1), and it is taking up an exorbitant amount of RAM (350-400MB).


Being a little curious, I looked in the System Monitor, right-clicked the Java process and clicked Memory Map.


Now the results of this are very interesting - I can see the JAR files that are loaded into RAM. It seems that the same JAR file is loaded in multiple times, taking up way more RAM than it should, intuitively.


Here is an extract of the memory map (the program happens to be the bittorrent client Azureus)



/usr/share/azureus/plugins/azupdater/azupdaterpatcher_1.6.3.jar VM Size = 82876K


/usr/share/azureus/plugins/azupdater/azupdaterpatcher_1.6.3.jar VM Size = 53760K


/usr/share/azureus/plugins/azupdater/azupdaterpatcher_1.6.3.jar VM Size = 38148K


This is the best example of this multiple classloading issue - there are other examples within the process. I've seen it occur with other JAR files, including the 'pango' GNOME font rendering library.


Is this normal, and could it be leading to the overusage of RAM? I have an intermediate knowledge of Linux/Java and haven't really studied the JVM much so I can only use my intuition here.


Over on the Azureus help forums they seem to be clueless so I'm imagining it's a JVM/OS thing.


By the way I'm running the following JVM:


java version "1.4.2_03"

Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)

Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)


Any ideas?
 
M Beck
Ranch Hand
Posts: 323
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
are you sure there's no overlap in those figures the System Monitor is giving you?

the reason a JAR (or a shared library, like Pango) would be referenced more than once in a process would most likely have to do with multithreading -- more than one thread accessing something in the JAR. but threads share address space; even full-weight processes share code and data copy-on-write. a shared library linked by more than one running process would only be loaded once, yet it would be listed by all the processes using it, and the entire size of it would be counted as part of each of those processes.

except, of course, for instance variables and other non-static data; they'd be copy-on-write and/or heap allocated. (threads complicate that issue a little bit; technically, they share instance data. but i believe there's a mechanism by which they can create thread-specific storage, too, if needed; i'm just not sure if it's used by default much in the JVM.) i suspect these might be the reason the different copies of the same JAR show up as different sizes in your list. even so, most of the size -- up to perhaps as much as the smallest of the listed sizes -- of each of those "copies" of the JAR would in reality be shared between them all, with only one copy actually loaded into real RAM. the rest is most likely a mirage, just a byproduct of related address spaces.

(that is, all assuming a JAR behaves like a shared library. it should; the JVM should be plenty smart enough to eliminate duplication this way -- if all those copies are actually real, then Sun has a lot of work to do! )
 
Ben Rowland
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thankyou for your reply, I hadn't thought about threads. Yes, you would imagine that objects would be shared throughout threads. Unfortunately, the 348MB RAM usage is confirmed in top, which I believe is quite reliable.

HOWEVER ... I've done a bit more research and it turns out that there's a bug in gnome-system-monitor that causes multiple references to a library or JAR when there shouldn't be. It turns out that the Java process allocates a whole chunk of 'anonymous memory' - the gnome system monitor fills in the library name with the last value it had rather than blanking it out. Hence the duplications.

Thing is, the RAM usage definitely is 348MB right now, verified in top, so I just need to figure out what this 'anonymous memory' is and why there's so much of it allocated!

Thanks for your help,

Ben
 
Ben Rowland
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Follow-up ... in case anyone else encounters this problem here is some useful stuff.

This command:

<code>
pmap <process-id>
</code>

will identify whether there is anonymous memory regions in a java process.

This technote from Sun seems to point the finger at memory leaks.
 
Ben Rowland
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Repost with correct formatting!

Follow-up ... in case anyone else encounters this problem here is some useful stuff.

This command:

<code>
pmap <process id>
</code>

will identify whether there are anonymous memory regions in a java process.

This technote from Sun seems to point the finger at memory leaks.
 
Guy Allard
Ranch Hand
Posts: 776
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does this app or anything it uses have custom/additional ClassLoader's?

Guy
 
Ben Rowland
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good idea ... Browsing through the CVS and the JAR listing it doesn't look like it though.

While browsing though, I found that it uses MemoryMappedFile classes, with use of the new I/O channels - looks interesting.

If these chunks of 'anonymous memory' DO relate to a memory leak then it has to be something slightly off the standard Java curve - after all, we don't do memory leaks in Java

I'll post more if I find anything.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!