Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Feb 2003 00:36:43 -0800
From:      Milo Hyson <milo@cyberlifelabs.com>
To:        Alexey Zelkin <phantom@FreeBSD.org.ua>
Cc:        FreeBSD Java Mailing List <freebsd-java@FreeBSD.ORG>
Subject:   Re: JVM choking
Message-ID:  <3E54939B.5080104@cyberlifelabs.com>
References:  <3E53A5DE.9080506@cyberlifelabs.com> <20030220001813.A51537@phantom.cris.net>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------060300090803020300010601
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Alexey Zelkin wrote:
> Do you have testcases for anylizis ?  I'd be interesting to take a look.

Yeah, see the attached file.

I've determined the problem to be an out-of-memory condition in the JVM 
(if I wait long enough it spits out an exception). It's curious however 
that the OS still reports having quite a lot of RAM free. I ran the 
attached test code without any command-line arguments and had the 
following results:

Test Case #1
------------
Athlon 1 GHz w/512 MB RAM
FreeBSD 4.7-RELEASE
Native JDK 1.3.1 w/Patchset 8
Died after 103000 entries, 277849 total nodes
140+ MB RAM still free according to the OS

Test Case #2
------------
Pentium II 400 MHz w/384 MB RAM
RedHat Linux 8
IBM JDK 1.4.1
Died after 461000 entries, 1029547 total nodes
60+ MB RAM still free according to the OS

It would appear that the memory manager in both JVMs is hitting some 
sort of self-imposed limitation, as neither OS was anywhere near running 
out of memory. Where exactly that limit is set seems to depend on which 
JVM is used.

-- 
Milo Hyson
CyberLife Labs

> On Wed, Feb 19, 2003 at 07:42:22AM -0800, Milo Hyson wrote:
> 
>>Has anyone run into any problems with their JVM choking on too many 
>>objects? I'm currently working on an application in which 1,000,000+ 
>>objects are in existence at any given time. When the program first 
>>starts up and begins creating the objects, things run very fast but soon 
>>begin to slow down. Available memory also drops rapidly. Eventually, 
>>everything grinds to a halt and it just sits there -- no disk activity, 
>>no network traffic, no output, but 100% CPU load. Several tens of 
>>megabytes of memory are still available so it's not out of RAM. After a 
>>minute or so of no activity, an exception begins to be displayed but 
>>never completes printing. There isn't enough of it shown to see what 
>>kind of exception it is. At that point, all I can do is hit Ctrl-C 
>>(which does kill it BTW).
>>
>>Anyone ever seen anything like this? I'm using the Native JDK 1.3.1 
>>w/patchset 8. The problem occurs both with and without a JIT, but seems 
>>to get further without it.
>>
>>-- 
>>Milo Hyson
>>CyberLife Labs
>>
>>
>>To Unsubscribe: send mail to majordomo@FreeBSD.org
>>with "unsubscribe freebsd-java" in the body of the message
> 
> 
> 

--------------060300090803020300010601
Content-Type: text/plain;
 name="NodeTest.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="NodeTest.java"


import java.util.*;


public class NodeTest
{
    private static long totalNodes  = 0;
    private static long maxChildren = 0;
    
    private Hashtable children;
    private String    name;
    
    public NodeTest(String name)
    {
        totalNodes++;
        
        children  = new Hashtable(1);
        this.name = name;
    }
    
    public void addChild(NodeTest child)
    {
        children.put(child.name,child);
        
        if (children.size() > maxChildren)
            maxChildren = children.size();
    }
    
    public NodeTest getChild(String name)
    {
        return (NodeTest)children.get(name);
    }
    
    public static void main(String args[])
    {
        // Default number of entries to add
        long numEntries = 1000000;
        
        // Default number of levels to create
        int numLevels = 5;
        
        // If there are any command-line arguments...
        if (args.length >= 1)
        {
            try
            {
                // ...parse the first one into a Long
                numEntries = Long.parseLong(args[0]);
            }
            catch (NumberFormatException e)
            {
                numEntries = 0;
            }
            
            // Make sure the number of entries is valid
            if (numEntries <= 0)
            {
                System.err.println("Invalid number of entries");
                System.exit(1);
            }
            
            // If there's a second argument...
            if (args.length >= 2)
            {
                try
                {
                    // ...parse it into an Integer
                    numLevels = Integer.parseInt(args[0]);
                }
                catch (NumberFormatException e)
                {
                    numLevels = 0;
                }
                
                // Make sure the number of levels is valid
                if (numLevels <= 0)
                {
                    System.err.println("Invalid number of levels");
                    System.exit(1);
                }
            }
        }
        
        // Create a random-number generator
        Random random = new Random();
        
        // Create the root node
        NodeTest rootNode = new NodeTest("<root>");
        
        // For each entry...
        for (long i=0; i<numEntries; i++)
        {
            NodeTest curNode = rootNode;
            
            // Descend the levels
            for (int j=0; j<numLevels; j++)
            {
                // Generate a random key
                String key = "" + random.nextInt(50);
                
                // Get or create an entry at that key
                NodeTest child = curNode.getChild(key);
                if (child == null)
                {
                    child = new NodeTest(key);
                    curNode.addChild(child);
                }
                
                // Next level
                curNode = child;
            }
            
            // Generate periodic status reports
            if ((i % 1000) == 0)
                System.out.println("Added " + i + " entries, totalNodes = " + totalNodes + ", maxChildren = " + maxChildren);
        }
    }
}

--------------060300090803020300010601--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-java" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E54939B.5080104>