RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Memory Usage/Garbage Collection

Mikey

Sorceror
Hi all, I'm trying to throw my server on a linux machine, currently it works fine on Windows (and appears to use half the memory).

So here's my problem, on linux I'm running the server and memory is creeping up fairly steadily. (Starts at 600 MB, it's at 685MB after being up for 2 hours 15 mins).

I know there is a way to force garbage collection with MemHelper.cs, but that uses Kernel32, which obviously isn't present on mono. Any suggestions on how to force garbage collection on a linux system, or anything glaringly obvious that I could do to prevent that much of a difference in memory, just from running?

Just for comparison, on Windows it uses ~250MB of memory, and stays fairly constant.

I'm not extremely concerned at this point, just kind of curious if there is a way to force garbage collection (say every 30 minutes) on linux.

I'm going to leave it up and see if it continues to rise, (and if it caps).

Thanks.
 

Soteric

Knight
Different architecture, different hardware, different OS, different CLRs. I think it's okay that you see different memory consumption :)
 

Mikey

Sorceror
Different architecture, different hardware, different OS, different CLRs. I think it's okay that you see different memory consumption :)
Shouldn't I be concerned that I'll eventually run out of memory? Considering it's still rising, and is at 723.6 MB up from 685 that I posted an hour ago.
 

Mikey

Sorceror
Yes, you should be concerned if it steadily rising. But I doubt it will rise over 1GB in your case. You should check it anyway.

http://www.runuo.com/community/threads/memory-leak-info.526685/ here is the similar problem. Probably the explanation provided there will be helpful.
Thanks for the link, I took a look at it, somewhat similar. The only thing that is bothering me is that on Windows it's steady, so that leads me to believe it's not the save files or the scripts. Or maybe I just have something that isn't linux-friendly, I'm not sure.

Is it possible to force a garbage collection, say every 30 minutes or so on linux?

MemHelper.cs does this on windows.
 

Soteric

Knight
What is MemHelper.cs? I don't see it in distro.

Actually you shouldn't call GC explicitly. If you have memory leak it won't help you anyway. If not then GC will do its job better without your instructions, believe me.
 

Vorspire

Knight
Code:
long memoryUsageBefore = GC.GetTotalMemory(false);
long memoryUsageAfter = GC.GetTotalMemory(true);
long freedMemory = memoryUsageBefore - memoryUsageAfter;

Use this code efficiently, you don't want to make too many manual calls to the Garbage Collection.
http://msdn.microsoft.com/en-us/library/system.gc.aspx

Rich (BB code):
using System;
using Server;

namespace Server
{
	public static class AutoGC
	{
		public static void Initialize( )
		{
			Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromMinutes( 5 ), delegate( )
			{
				long before;
				long after;

				Collect( out before, out after );

				Console.WriteLine( "[AutoGC]: Using: {0}, Freed: {1}, Current: {2}", 
						Format( before ), Format( before - after ), Format( after ) );
			});
		}

		public static void Collect( out long before, out long after )
		{			
			before = GC.GetTotalMemory(false);
			after = GC.GetTotalMemory(true);
		}

		public static string Format(long totalBytes)
		{
			if (totalBytes >= 1024000000)
				return String.Format("{0:F2} GB", (double)totalBytes / 1024000000);

			if (totalBytes >= 1024000)
				return String.Format("{0:F2} MB", (double)totalBytes / 1024000);

			if (totalBytes >= 1024)
				return String.Format("{0:F2} KB", (double)totalBytes / 1024);

			return String.Format("{0} B", totalBytes);
		}
	}
}
 

Mikey

Sorceror
Code:
long memoryUsageBefore = GC.GetTotalMemory(false);
long memoryUsageAfter = GC.GetTotalMemory(true);
long freedMemory = memoryUsageBefore - memoryUsageAfter;

Use this code efficiently, you don't want to make too many manual calls to the Garbage Collection.
http://msdn.microsoft.com/en-us/library/system.gc.aspx

Rich (BB code):
using System;
using Server;
 
namespace Server
{
public static class AutoGC
{
public static void Initialize( )
{
Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromMinutes( 5 ), delegate( )
{
long before;
long after;
 
Collect( out before, out after );
 
Console.WriteLine( "[AutoGC]: Using: {0}, Freed: {1}, Current: {2}",
Format( before ), Format( before - after ), Format( after ) );
});
}
 
public static void Collect( out long before, out long after )
{
before = GC.GetTotalMemory(false);
after = GC.GetTotalMemory(true);
}
 
public static string Format(long totalBytes)
{
if (totalBytes >= 1024000000)
return String.Format("{0:F2} GB", (double)totalBytes / 1024000000);
 
if (totalBytes >= 1024000)
return String.Format("{0:F2} MB", (double)totalBytes / 1024000);
 
if (totalBytes >= 1024)
return String.Format("{0:F2} KB", (double)totalBytes / 1024);
 
return String.Format("{0} B", totalBytes);
}
}
}
I implemented your first part of the post you posted, waited 30 minutes and then it executed it (executes every 30 minutes)

Here's what happened:

initial ram usage when started up: 527 mb
30 minutes later: 537 MB
after code was executed: 527.5 mb
freedMemory = 10608640
Seems to be working good. Thanks!
 
Top