|
-
March 17th, 2009, 08:08 PM
#16
Re: How to prevent outofmemory exeption?
Not that I know of. This is the code that reads a row:
Code:
Console.WriteLine("Loading Mobiles...");
if(!Core.SQLCON.Query("SELECT * FROM mobiles;"))
{
Console.WriteLine("Error loading mobiles! This is fatal and stuff. Terminating");
Console.ReadKey();
return;
}
m_Mobiles = new Dictionary<Serial, Mobile>();
while(Core.SQLCON.FetchRow())
{
int serial = Core.SQLCON.Reader.GetInt32(0);
string serialstr = serial.ToString();
int typeid = Core.SQLCON.Reader.GetInt32(1);
string typestr = Core.SQLCON.Reader.GetString(2);
string serializedata = Core.SQLCON.Reader.GetString(3);
//Do stuff, store serializedata in an array to be used later, then discarded
}
serializedata is the string that gets very large. I checked my DB and the biggest one I got is 80k. I can't see it getting any bigger then 100k per, though, but it is possible. This process is only required at the very start of app startup. Once the string array is processed then the string is broken up into variables (smaller strings, ints, bools, etc).
It's not the best storage engine, idealy I should be structuring everything into a proper SQL structure, but that would require a HUGE rewrite that I'm not ready to do. I rather go this method and just optimize as best as I can.
I was able to store over 1GB of data in a C++ string, and to top it off I was using concatenation with += and it was a non brainer, so I'm sure there must be a way to get C# to allow this too.
And again, ram is not the issue as I have over a gig free during this operation, and even if it was, then it should be using the swap file.
-
March 18th, 2009, 05:22 AM
#17
Re: How to prevent outofmemory exeption?
What is Core.SQLCON.Reader ?
Does it have a GetChars method like IDataRecord.GetChars ?
If so, you can avoid reading that string in one go.
-
March 18th, 2009, 06:24 AM
#18
Re: How to prevent outofmemory exeption?
 Originally Posted by Zaccheus@Work
What is Core.SQLCON.Reader ?
Does it have a GetChars method like IDataRecord.GetChars ?
If so, you can avoid reading that string in one go.
I am 99% certain that IDataRecord.GetChars(..) uses an internal buffer. If this buffer is in managed code, then it does nothing to address the LOH issue. If it is in native code, then it may help.
It would require some fairly deep code analysis to determine, but even that may be a waste of time since the method is NOT documented either way (and thus a change could occur at anytime without violating the contract). Counting on undocumented implementation behaviour is always dangerous.
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions 
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
March 18th, 2009, 07:06 AM
#19
Re: How to prevent outofmemory exeption?
There are two easy steps to figuring out the cause:
Step 1) Profile your application
Step 2) Diagnose the actual issue
Step1)
The CLRProfiler should be good enough for the task (http://msdn.microsoft.com/en-us/magazine/cc163491.aspx)
Step 2) If you don't understand the output of the CLR Profiler, paste screenshots of the graphs here (or online somewhere) and I'll try and diagnose the issue for you. Until you profile, you're just making random guesses as to what you think is happening.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
March 18th, 2009, 04:30 PM
#20
Re: How to prevent outofmemory exeption?
The SQLCON object looks like this:
Code:
using System;
using System.IO;
using MySql.Data.MySqlClient;
namespace Server
{
public class SqlConnector
{
private MySqlConnection m_con;
private MySqlDataReader m_Reader;
public MySqlDataReader Reader { get {return m_Reader;} }
private string m_lasterror;
public string GetLastError()
{
return m_lasterror;
}
private void ThrowError(string query,string error)
{
m_lasterror=error;
Debugger.Write("mysql","Query: {0} ---------- Error: {1}",query,error);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("--- SQL ERROR ---");
Console.WriteLine(query);
Console.WriteLine("---------");
Console.WriteLine(error);
Console.WriteLine("--- END SQL ERROR ---");
Console.WriteLine("");
Console.WriteLine("");
}
public bool Connect()
{
try
{
//connect to mysql server:
string connString = "";
StreamReader tr = new StreamReader("data/sqlconf.txt");
connString = tr.ReadLine();
tr.Close();
//create your mySQL connection
m_con = new MySqlConnection(connString);
m_con.Open();
}
catch (Exception ex)
{
ThrowError("Connect to DB",ex.ToString());
return false;
}
Debugger.Write("mysql","Connect to DB");
return true;
}
public void Disconnect()
{
if(m_con==null)return;
Debugger.Write("mysql","Disconnect from DB");
m_con.Close();
}
public bool Query(string query)
{
try
{
if(m_Reader!=null) m_Reader.Close();
MySqlCommand command = m_con.CreateCommand();
command.CommandText = query;
m_Reader = command.ExecuteReader();
}
catch (Exception ex)
{
ThrowError(query,ex.ToString());
return false;
}
Debugger.Write("mysql","Query:{0}",query);
return true;
}
public bool FetchRow()
{
if(m_Reader==null || !m_Reader.Read())return false;
return true;
}
}
}
I have not been able to reproduce the issue lately but I'll try to force it some time.
Though if it keeps working properly it may buy me some time to further optimize my load sequence as there's a few things I can do to avoid having to load ALL the strings into memory at once, which may possibly be part of the problem.
-
March 18th, 2009, 05:50 PM
#21
Re: How to prevent outofmemory exeption?
Have your process crash with an OOM isn't necessary to see if it's a garbage collection issue. Just run the app through a normal startup sequence (or even better, a really stressful one - load everything three times in a loop) and then look at the results in the memory profiler. If you see a lot of data retained in memory, then you've found an issue. If you don't, then it's not the loading sequence causing the issue.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|