Project

General

Profile

Bug #5576

memory leak in ptolemy.data.expr.CachedMethod

Added by Daniel Crawl over 7 years ago. Updated about 7 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
Category:
general
Target version:
Start date:
02/17/2012
Due date:
% Done:

0%

Estimated time:
Bugzilla-Id:
5576

Description

There is a memory leak in CachedMethod where the same method is inserted multiple times into the static hash table _cachedMethods. You can see this by running the attached model created by Jianwu. The model has an Expression actor, which uses trim(), isEmpty(), split(), and map(). The model iterates 1000 times, and afterwards jmap reports there are 1004 CachedMethods in the heap:

jmap -histo:live 6959 | grep CachedMethod
38: 1004 40160 ptolemy.data.expr.CachedMethod

Most of these CachedMethods are for map(). The problem is that each CachedMethod for map() has a different hash code. The hash code for a CachedMethod is computed by using the method's argument types and map()'s first argument is a FunctionType. The hash code for FunctionType is based on the hash code for FieldTypeTerm, which is unique for each instance since it does not override Object.hashCode().

cachedmethod-leak.xml (24.6 KB) cachedmethod-leak.xml Daniel Crawl, 02/17/2012 03:21 PM

History

#2 Updated by Christopher Brooks over 7 years ago

This is possibly fixed in r63763 in the ptII tree.
Basically, I had to add better equals() and hashCode() methods to
FunctionType and FunctionType.FieldTypeTerm.

BTW - getting equals() and hashCode() right is tricky.
I found a good document at
See http://www.technofundo.com/tech/java/equalhash.html

To test the bug
1) Download the attachment above:
http://bugzilla.ecoinformatics.org/attachment.cgi?id=397

2) Start up Kepler, open the model, run it

3) Start up jvisualvm

4) Connect to the Kepler process, Monitor -> Perform GC, generate a heapdump

5) In the heapdump window, click on classes and then search for Cached

Formerly, there were about 1000 entries, now there are many fewer.

Currently, CachedMethod has two entries for map. It looks like
they are different because of the number of array elements.

I temporarily added a static dump() method to CachedMethod that merely called
System.out.println(_cachedMethods)
I then temporarily added code to Manager that called CachedMethod.dump()

The output is below.

{map((function(a0:string) {key = string, value = int}),
arrayType(string,5))= map((function(a0:string) {key = string, value =int}),
arrayType(string,5)),
map((function(a0:string) {key = string, value = int}),
arrayType(string))= map((function(a0:string) {key = string, value = int}),
arrayType(string)),
string.split(string)=string.split(string),
string.isEmpty()=string.isEmpty(),
string.trim()=string.trim()}

I don't think there is much we can do about this, but I'm open to suggestions.

I think this is ready to be closed, I'm dispatching it back to Daniel for his
approval.

#3 Updated by Daniel Crawl about 7 years ago

I ran the attached model and this looks fixed to me. Previously, each execution added about 1000 instances of ptolemy.data.expr.CachedMethod. Currently there are only 2 instances regardless of how many times the model executes. Thanks, Christopher!

#4 Updated by Redmine Admin over 6 years ago

Original Bugzilla ID was 5576

Also available in: Atom PDF