users@glassfish.java.net

Re: Jsr199JavaCompiler possible memory leak?

From: <glassfish_at_javadesktop.org>
Date: Thu, 15 Jan 2009 04:24:57 PST

Hey there, I may have been a bit quick off the mark as a heap dump shows the same behaviour still happening.

Bit more thinking and the ArrayList will never find a match for one version of a class in Bytecode form with the default implementation of the equals(Object o) method

Suggest overriding the equals(Object o) within the BytecodeFile definition to something like:

[code]
        public boolean equals(Object o) {
                if ( !(o instanceof BytecodeFile) ) return false;
 
                return this.getClassName().equals(((BytecodeFile)o).getClassName());
        }

[/code]

Im sure you could do something more elegant with hashcode but according to java api docs this is more relevant for searching within maps.

Then also make sure that all instances are properly removed before adding a new instance.

[code]
    private JavaFileObject getOutputFile(final String className,
                                         final URI uri) {
 
        BytecodeFile classFile = new BytecodeFile(uri, className);
 
        // File the class file away, by its package name
        String packageName = className.substring(0, className.lastIndexOf("."));
        Map<String, ArrayList<Object /*JavaFileObject*/>> packageMap =
            rtctxt.getPackageMap();
        ArrayList<Object/*JavaFileObject*/> packageFiles = packageMap.get(packageName);
        if (packageFiles == null) {
            packageFiles = new ArrayList<Object/*JavaFileObject*/>();
            packageMap.put(packageName, packageFiles);
        }
 
        /* start patch */
        /* scan through the list to make sure that it removes all previous instances
         * of the compiled class ArrayList.remove(Object o) just removes first
         * instance found so potential for leak still exists */
        ArrayList<Object> matches = new ArrayList<Object>();
        for ( Object o : packageFiles ) {
                if ( ((BytecodeFile)o).getClassName().equals(className) ) matches.add(o);
        }
 
        for ( Object m : matches ) {
                packageFiles.remove(m);
        }
        matches.clear();
        matches = null;
 
        // then add it to keep most recent copy
        /* end patch */
        packageFiles.add(classFile);
        classFiles.add(classFile);
        return classFile;
    }


[/code]
[Message sent by forum member 'finbarro' (finbarro)]

http://forums.java.net/jive/thread.jspa?messageID=326188