Skip to main content

Possible memory leak?

5 replies [Last post]
suntzu2007
Offline
Joined: 2010-05-25
Points: 0

Hi all,

I'm having some performance issues with a Java application that I am developing (an AIS monitor that receives AIS feeds from a server and displays the located vessels, their status information and the coverage area of the AIS receiver). After approximately 7 - 10 minutes, the application just becomes unresponsive and crashes. No exceptions are thrown. I think that this is due to a memory leak in the code snippet below (reasons for this are twofold: 1) if the snippet is omitted, the application behaves as expected. 2) I used the Netbeans profiler to profile the application. It shows a large amount of surviving Position() objects. Unfortunately, when I do a stack trace, the profiler crashes. I have tried this on several machines (and under both Windows and Mac OSX), and the profiler keeps crashing when taking a snapshot or asking it to do a stack trace)).

Could somebody explain to me why some resources are not being collected by the garbage collector? I tried running System.gc, finalizing objects manually etc, but without any luck. Since I am de-referencing all objects with each loop (tmpList and pos are declared outside the loop), shouldn't become collected?

Thanks for your time :-)

distanceMap = initDistanceMap(new ConcurrentHashMap(3600));
coveragePerimeter = new ArrayList(3600);
Thread coverageCalculatorThread = new Thread(new Runnable() {

public void run() {
List tmpList;
Position pos;
while (true) {
try {
calculateCoveragePerimiter();
tmpList = new ArrayList(3600);
// Add any non-null positions to the geo-position list so
// that they can later form the points for the coverage polygon
for (Double key : distanceMap.keySet()) {
if (distanceMap.get(key).getPosition() != null) {
tmpList.add(key);
}
}
// Sort the positions according to their appearance from 0 to 360 degrees
Collections.sort(tmpList);
for (Double key : tmpList) {
pos = new Position(distanceMap.get(key).getPosition().getLatitude(),
distanceMap.get(key).getPosition().getLongitude());
coveragePerimeter.add(pos);
}
pos = new Position(getLocation().getLatitude(),
getLocation().getLongitude());

coveragePerimeter.add(pos);
// Sleep five seconds
pos = null;
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
suntzu2007
Offline
Joined: 2010-05-25
Points: 0

thanks walterln. That did the trick.

suntzu2007
Offline
Joined: 2010-05-25
Points: 0

Thanks walterln! What a foolish thing of me to do. I feel stupid now :D I'll make the changes when I come home tonight. Hopefully that was it :-)

walterln
Offline
Joined: 2007-04-17
Points: 0

Every five seconds you add X+1 (3600+1 based the initial capacity) Position objects to coveragePerimeter. You never remove them (unless calculateCoveragePerimiter() has some side effect).

You could re-use the tmpList to avoid creating a new Position[3600] every five second, but at least those are collected.

dwormald
Offline
Joined: 2008-05-05
Points: 0

It looks like it depends upon what initDistanceMap is doing.
The best thing, if you suspect a leak, is to force a heapdump. It will tell you if your program is leaking. Then, collecting two heapdumps is best: look at the differences in instance counts between the two; then track down the references to those objects.

suntzu2007
Offline
Joined: 2010-05-25
Points: 0

Thanks! I will give it a ago tonight. Will let you two know how it went. Thanks for you time.