Bug - Cannot Reproduce Chat related memory problem

meow

New member
Hi,

I like to leave mafia going on through the whole day so I can chat throughout the day. If I start a new mafia instance, the memory used is small and all is well. As the day goes on and I keep on chatting, the memory size used by mafia increases and cannot be cleared. Within a few hours mafia becomes unresponsive to anything I want to do because it seems to use as much memory as it is allowed (200+ MB). If I log out and then log back in, I start with as much memory hogged as before ( something like 10k less but still near the 255mb limit). If log out and log in with a different account the same problem exists. Effectively I have to close mafia and start a whole new instance.

I am currently using r11894 but the problem existed from previous versions as well. I would love it if this were fixed because I very much love using the mafia chat window to keep my chats organized.

meow
 

roippi

Developer
I assume you've tried running it over that length of time without chat open and haven't had the memory leak issue?
 

meow

New member
I assume you've tried running it over that length of time without chat open and haven't had the memory leak issue?

Yes. Sorry meant to mention that. I have ran the same mafia version over the same length of time, one on my multi one on my main with the multi chat closed and the main chat opened and the multi i.e. non chat option is fine.
 
Last edited:

Erich

Member
Same thing happens to me, but I didn't know it was chat, I thought it was my computer. Restarting mafia does reset the leak though.
 

roippi

Developer
Looking at ChatPoller.getEntries() I could certainly believe there's a memory leak. That does a couple of things that makes my head spin.

Unfortunately the chat subsystem is really not my thing but if there are no takers I can give it an I-make-no-promises crack. I dunno, I wish grotfang was still around.
 

meow

New member
Looking at ChatPoller.getEntries() I could certainly believe there's a memory leak. That does a couple of things that makes my head spin.

Unfortunately the chat subsystem is really not my thing but if there are no takers I can give it an I-make-no-promises crack. I dunno, I wish grotfang was still around.

Hope it is allowed to bump this up.
 

fronobulax

Developer
Staff member
I almost never use chat but I do get a perverse pleasure tracking down memory leaks. The good news is that this is on the top of my personal mafia "ToDo" list. The bad news is that I'm going to have to free up several hours from Real Life to look at it. So it is on the radar for at least two devs although that is no guarantee of anything.
 

fronobulax

Developer
Staff member
I had a few minutes with tools. Chat definitely allocates a lot of memory but manual garbage collection frees a lot of it. Did not have time to figure out who liked to allocate char[].
 

meow

New member
I had a few minutes with tools. Chat definitely allocates a lot of memory but manual garbage collection frees a lot of it.


While at a first glance manual garbage collection works, it actually doesn't -- within 30-90 seconds whatever the manual garbage collection freed up is eaten back up.
 

fronobulax

Developer
Staff member
Hi,

I like to leave mafia going on through the whole day so I can chat throughout the day. If I start a new mafia instance, the memory used is small and all is well. As the day goes on and I keep on chatting, the memory size used by mafia increases and cannot be cleared.

What do you mean by "cleared"? How are you trying to "clear" it? From the technical side I'm trying to figure out whether something is holding on to memory unnecessarily, or whether garbage collection is not aggressive enough. Should have asked this before but are there any debug logs with messages such as "Out of Heap Space"?

Within a few hours mafia becomes unresponsive to anything I want to do because it seems to use as much memory as it is allowed (200+ MB). If I log out and then log back in, I start with as much memory hogged as before ( something like 10k less but still near the 255mb limit). If log out and log in with a different account the same problem exists. Effectively I have to close mafia and start a whole new instance.

When you say "allowed" who or what is doing the allowing? Are you running mafia with a command line switch such as -Xmx256m?

If mafia is using all of the memory it can get from the operating system then the only way to free it would be to shut down mafia and restart it so I am not surprised that logging in and out do nothing.

I'm wondering if there are two problems here? One would be that mafia's normal memory requirements are very close to exceeding the capabilities of your computer and environment as currently configured. That's your problem, although we will be glad to try and help. The other possible problem is that mafia could make better use of the memory it uses. Given that garbage collection does reduce the memory footprint for me I'm not certain there is a leak in the traditional sense - programatically keeping memory allocated when it is no longer needed.

All that said, there does seem to be something with chat that causes memory usage to climb.
 

fronobulax

Developer
Staff member
Is there an upper limit on the chat buffer?

What do you mean? I think there is a buffer of fixed size and new text pushes out old text as needed. Thus once allocated, the buffer will consume constant memory. I could be wrong since I am basing this on a recollection that chat is one of several classes that use the same buffer class because I recall needing to change some other buffer and a side effect was changing the chat buffer.
 

roippi

Developer
It's a little more insidious than just maintaining a line of text for each chat entry. Longwinded post coming up.

ChatPoller.getEntries snippet:

Code:
		ChatRequest request = null;

		request = new ChatRequest( ChatPoller.serverLastSeen );
		request.run();

		HistoryEntry entry = new HistoryEntry( request.responseText, ++ChatPoller.localLastSeen );
		ChatPoller.serverLastSeen = entry.getServerLastSeen();

		newEntries.add( entry );

		ChatPoller.chatHistoryEntries.add( entry );
		ChatManager.processMessages( entry.getChatMessages() );

And I won't post it, but ChatManager.processMessages maintains a number of strong references to entry, so entry sticks around. Which is what you want... kinda. Ideally you just want a lightweight string instead of the bulkier object, but that's just streamlining.

Unfortunately the above code has at least one memory leak in it. I'll go through it.

Code:
		request = new ChatRequest( ChatPoller.serverLastSeen );
		request.run();

Polling the server for new chat entries.

Code:
		HistoryEntry entry = new HistoryEntry( request.responseText, ++ChatPoller.localLastSeen );

Creating a new HistoryEntry object. Note that HistoryEntry now contains a strong reference to request.responseText; the ChatRequest object therefore is not available for garbage collection and will not disappear until the HistoryEntry object does, too. When you're coding stuff like this you can usually think of request.responseText as just another string, but in fact it's a field belonging to request.

A quick fix is to do new HistoryEntry( new String( request.responseText ) ... since that makes java allocate a new String for just the thing you want, allowing the request object to be GC'd. Anyway, continuing with explaining the memory leak...

Code:
		ChatPoller.chatHistoryEntries.add( entry );

This would be a memory leak, but chatHistoryEntries is a RollingLinkedList which automatically pops the oldest entry off when adding a new one. So no issue there.

Code:
		ChatManager.processMessages( entry.getChatMessages() );

The memory leak. getChatMessages() returns a field of entry, and processMessages goes on to create a number of strong references (i.e. unavailable for gc) to that field, such as

Code:
			ChatManager.clanMessages.add( message );

etc. Entry is never GC'd, and therefore the ChatRequest is never GC'd.

While this should be fixed, I have a feeling it's not sufficient to completely gobble up hundreds of MB of RAM by itself, so I'm going to keep going through the chat system. I have a feeling there are others.
 

lostcalpolydude

Developer
Staff member
If you come out of this understanding how it all works, maybe new chat support can be added? I know I said I was going to work on that, but I haven't even looked at it in months.
 

roippi

Developer
Probably not.

Either way I'm leaving chat open until rollover and gathering heap dumps, so we'll see.

(note: if you have a jdk installed, try playing around with jdk/bin/jvisualvm.exe. It's cool)
 
Top