JDK-4962665 : 8MB of memory chews up by jdk1.4.2 on solaris
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.4.2
  • Priority: P2
  • Status: Closed
  • Resolution: Won't Fix
  • OS: solaris_8
  • CPU: sparc
  • Submitted: 2003-12-03
  • Updated: 2006-06-22
  • Resolved: 2006-06-22
Related Reports
Relates :  
Relates :  
Description
Our partner Motorola reports the following:
mototrola 2003-12-03:
=====================
>Basically, our Cork development team has decided that
>because of the overhead of a single JVM on Solaris they (Cork Development)
>will not be using Java, at this time, to development stand alone client
>applications.  We will be going ahead with our piloting of J2EE development
>
>Just so you guys are aware of this, with JDK 1.4.2 on Solaris 8 and 9, a
>simple program that prints the string "Hello World" to the terminal chews up
>8MB of physical memory (according to our tests), and it just gets worse from
>there..   This does not change with either the hotspot or "traditional" JVM.
>There's a big opportunity here for Sun to make improvements here.
>

###@###.### 2003-12-03:
==================================

This issue can be reproduced using the attached zip file and following:

$> cd /tmp
$> unzip prototype.zip
$> rmiregistry &
$> export CLASSPATH=/tmp/prototype.jar
$> java -Djava.rmi.server.codebase=file:///tmp/prototype.jar -Djava.security.policy=server.policy prototype.server.FactoryEngine

in an other window:
$> cd /tmp
$> export CLASSPATH=/tmp/prototype.jar
$> java -Djava.rmi.server.codebase=file:///tmp/prototype.jar -Djava.security.policy=server.policy prototype.client.launcher

The client window of the prototype then shall appear.

Environment:

$> java -version
java version "1.2.2"
Solaris VM (build Solaris_JDK_1.2.2_10, native threads, sunwjit)

Motorola's note:
> I've also run this app on 1.4.2, and have had the same memory problems.


OS Version:

$> uname -a
SunOS somc58 5.8 Generic_108528-13 sun4u sparc SUNW,Netra-T4

Comments
EVALUATION Although some headway has been made, this RFE will be closed as will not fix. Read on for an explanation. This RFE has boiled down to a request for significant footprint decrease in small-medium sized single-VM applications. While we've made some progress (real footprint or RSS as measured by refWorkload is down 19% on Solaris SPARC from 1.4.2_11 to Mustang b88, perceived or VSZ down 38%), realistically, we should not expect any drastic footprint reductions on the horizon in the single-VM case. That said, we do very much want to continue to find and implement incremental footprint improvements, particularly in the case of multiple VMs via increased sharing, but also in the single-VM case. It's just that there should not be an expectation for such drastic footprint decreases as requested in this RFE.
22-06-2006

PUBLIC COMMENTS This bug has been converted to an RFE to be combined with other footprint related RFEs for J2SE.
10-06-2004

EVALUATION There is a 1.5 footprint effort under way to help in this area. ======================================== A suggestion from the RMI perspective: What is the intended lifecycle of the rmiregistry process for this application? Is it the same as the lifecycle of the remote object server process? (Or can it made to be? Or in other words, is it not expected to hold bindings for remote objects of other server processes as well?) If so, then the registry could be started programmatically in the same virtual machine as the remote object itself instead. Doing that would remove the overhead of the whole rmiregistry virtual machine, and it should add very little overhead to the main server process (which should already have the RMI subsystem implementation loaded). An RMI registry can be started programmatically (in the current virtual machine) with one of the "createRegistry" static methods of the java.rmi.registry.LocateRegistry class. ###@###.### 2003-12-12 Beyond the issue of using a separate VM for the registry (covered in the previous Evaluation entry above), it's not clear if there is more to do with this bug (at least specific to RMI). The Description states: ...with JDK 1.4.2 on Solaris 8 and 9, a simple program that prints the string "Hello World" to the terminal chews up 8MB of physical memory (according to our tests), and it just gets worse from there. I tried running the supplied test case, as well as some other, simple Java programs, using J2SE 1.4.2 and the client VM on Solaris 8. Using prstat, I recorded the steady-state SIZE and RSS values for each of the following cases: SIZE RSS ---- --- HelloWorld 48M 8408K rmiregistry (empty) 52M 10M rmiregistry (after first binding) 55M 14M TestImpl (after startup) 50M 13M TestImpl (after a client invocation) 50M 13M FactoryEngine (after startup) 58M 27M FactoryEngine (after launcher executed) 122M 27M HelloWorld is the simple Java "hello world" program with a Thread.sleep at the end to keep the VM alive for measurement. The RSS value of 8M seems consistent with the customer's statement above. TestImpl is a Java program that just exports a remote object and binds it to the registry. The registry bind invocation and the subsequent DGC "dirty" callback cause most of the RMI subsystem to be loaded and initialized at startup. FactoryEngine is the supplied test case. Upon startup, it exports a remote object, binds it to the registry, and creates some GUI (Swing) objects. The "launcher" is the client program (prototype.client.launcher) to run with the supplied test case, as described in the Description-- it just invokes a remote method on the server (StatusFactory.loadChannelStatus) and then exits. That remote method invocation causes the server process to display a "Channel Status" window. Comparing the results for the simple RMI server program (TestImpl) with the supplied test case (FactoryEngine), both relative to the baseline of the HelloWorld results, it does not appear to me that the use of RMI is the most significant factor in the size of the server process of the supplied test case. Running with -verbose shows that TestImpl loads 591 classes, and FactoryEngine loads 1456 classes. Of those 1456, 788 are Swing, AWT, or Java2D classes. Both of them load about 100 RMI classes. ###@###.### 2003-12-23 One more addition to the above results: FactoryEngine (with no RMI usage) 123M 26M In other words, when FactoryEngine is modified to not use any RMI (with a local invocation of loadChannelStatus instead), the process SIZE and RSS values end up being almost the same as the case when RMI is used. In that case, FactoryEngine loads 1215 classes (with essentially no RMI classes loaded). ###@###.### 2003-12-23 Transferring to Swing to do an evaluation. ###@###.### 2004-01-05 I ran some tests to see how we're doing in 1.5. My results are: HelloWorld: ----------- 1.4.2 -client : 8512K 1.4.2 -server : 10M 1.5 -Xshare:on : 10M 1.5 -Xshare:off : 11M 1.5 -server : 12M FactoryEngine (4962665 Test Case): ---------------------------------- 1.4.2 -client : 28M 1.5.0 -Xshare:on : 31M 1.5.0 -Xshare:off : 34M For comparison, I also ran a Swing-heavy test: SwingSet2: ---------- 1.4.2 -client : ~85M 1.4.2 -server : ~110M 1.5 -Xshare:on : ~76M 1.5 -Xshare:off : 80M 1.5 -server : ~97M This suggests that we're looking at an increase in VM overhead in 1.5. Swing itself, though, seems to have shed several megs of footprint. ###@###.### 2004-02-11 No resources available to address this issue in tiger timeframe. ###@###.### 2004-03-02 Although this is clearly out of scope for Tiger this bug deserves further investigation. ###@###.### 2004-03-04 Here is the exact virtual memory usage by J2SE of the "prototype" program on a Sparc Solaris 9 system (server+1 client GUI instance): Java rev Total Resident ReadOnly Modified Shared 1.2.2 45688 32648 10944 21704 - 1.3.0 32872 21944 11288 10656 - 1.3.1 34024 21288 11120 10168 - 1.4.0 48672 24560 10360 14200 - 1.4.1 50808 25216 9544 15672 - 1.4.2 65400 32192 11024 21168 - Here are the same numbers for a "Hello world" program that suspends itself after output: Java rev Total Resident ReadOnly Modified Shared 1.2.2 30496 7624 4600 3024 0 1.3.0 26280 7648 4696 2952 8 1.3.1 27744 6784 3864 2920 8 1.4.0 39048 8584 4968 3616 8 1.4.1 42248 7304 3968 3336 8 1.4.2 56912 7608 4824 2784 8 Column header definitions: Total: All virtual memory mappings of the process: regardless of usage or any possibility of usage in the future (i.e. whether there is or ever will be an association with physical memory). Think of this the sum of the text, data, and stack areas plus the sum of the total sizes of all memory mapped files of any type. Resident: Every referenced virtual memory page (read or written), minus shared counts if more than one process ("x2" above) to count pages in one process only. ReadOnly: Pages that can only be read or those that have only been read, only counted once if mapped into multiple processes. Modifed: Dirty pages: a write has happened with these, only counted once. Shared: count of pages in multiple processes ###@###.### 2004-04-29
29-04-2004