I have the following statement in a C# 2008 windows application that was converted to a console application:
finally
{
Console.ReadLine();
Environment.Exit(1);
}
The error message that is displayed says there is not enough io memory.
Can tell show me in code and/or point me to a reference that will show me how to solve this problem?
Loading
VulpesPosted Mar 4, 2013, 9:57 AM
dcPosted Mar 4, 2013, 9:34 AM
VulpesPosted Mar 4, 2013, 7:06 AM
Generally speaking, the .NET applications which have the highest memory footprint are those which use very large arrays, Lists or other collections (all .NET collections use arrays internally).
If app2 does have such collections, I'd try and estimate how much memory is needed to accommodate them.
For example, if you have an array of 10 million ints, this will use 40 million bytes because each int needs 4 bytes.
Similarly, 10 million doubles (8 bytes each) requires 80 million bytes of storage.
However, an array of 10 million strings will require 40 million bytes in a 32 bit app or 80 million bytes in a 64 bit app for the string references alone. The memory used by the strings themselves will be in addition.
So if the average length of the strings were 10 (unicode) characters, the average string would need 28 bytes (32 bit) or 36 bytes (64 bit) of storage including overhead of 8 and 16 bytes respectively. When you multiply these figures by 10 million, it's easy to see how memory usage can build up.
Although the typical machine has about 1.4 GB of usable memory, because of shortcomings in the way .NET deals with large object (85K bytes or more) you'll usually run out of memory well before then.
dcPosted Mar 3, 2013, 9:37 PM
VulpesPosted Mar 3, 2013, 7:04 PM
dcPosted Mar 3, 2013, 12:02 AM
1. To look at what is actually causing the memory problem, can I look at something like a call stack, a trace stack, and/or some other features in visual studio.net 2008 and/or visual studion.net 2010 professional editions? If so, can you tell me how to use the selected feature in visual studio?
2, Are other items I can use to determine what is causing the memory problem? Can I use something like task manager, sql profiler, an open source tool? What would you recommend and can you point me to directions on how to use the tool(s) you are recommending?
VulpesPosted Mar 2, 2013, 5:45 PM
By convention, a value of 0 means the process ended normally without error and a non-zero value means that termination was abnormal for some reason or another. I usually use 1 myself for non-specific errors but you can use any value you like.
2. The parameter to the WaitForExit() method specifies the number of milliseconds to wait. So 1800 waits for 1.8 seconds.
If each instance of the process is uploading and downloading multiple Office and pdf files, this isn't going to be anywhere near enough as these files tend to be large even if there's not much in them.
You can only really determine how long is needed by measuring the time taken for the process to run over a reasonably large number of iterations (say 100) but I wouldn't be surprised if it ran into several minutes.
5 minutes in milliseconds is 5 * 60 * 1000 = 300000
and 10 minutes is therefore 600000.
3. Just noticed that the emboldened code in my previous post should have been:
as we only want to wait a second time if it's been necessary to kill the process.
dcPosted Mar 2, 2013, 5:09 PM
1. For the statement-Environment.Exit(1);, do you think I should change the statement to Environment.Exit();, Can you tell me if this is a good idea, why or why not?
2. For the statement,
eProcess.WaitForExit(1800); Can you tell me what a reasonable amount of time would be?
Basically this process needs to upload and download lots of excel, word, and pdf documents to a web service?
Do you think, 5 or 10 minutes would be reasonable?
In the wait statement, can you tell me what 5 minutes is and what time 10 minutes is?
VulpesPosted Mar 2, 2013, 3:40 PM
dcPosted Mar 2, 2013, 2:00 PM
The following is an example of some of the calls made from app1 to the C# 2008 application that is having the memory problem called app2.
string[] SubPkgIDs = rData.details.Where(c => c.Package_ID.StartsWith("SUB").Select(c => c.PackID).Distinct().ToArray();
foreach (string SubPkgID in SubPkgIDs)
{
{
Process eProcess = new Process();
String Process_Arguments = null;
eProcess.StartInfo.UseShellExecute = false;
e_Process.StartInfo.FileName = "app2.exe";
Process_Arguments = " 3 " + SubPkgID;
eProcess.StartInfo.Arguments = Process_Arguments;
eProcess.Start();
eProcess.WaitForExit(1800);
//eProcess.WaitForExit();
eProcess.Dispose();
Process_Arguments = null;
}
}
I think the line of code that is causing the memory problem possibly is the following:
eProcess.WaitForExit(1800);
App1 is not waiting for a response basically from app2.exe program that is being called. It waits the 1800 *.secs and makes
the next calls. There is no reason for app1 to wait or app2 to finish executing since it does not need a response from app2.
However if this is causing the memory problem I can wait for the app2 program to finish executing.
App1 and app2 were setup to be single threaded.
In the app1 program that calls the second program called app2, I am thinking of putting the following code at the end of the program:
foreach (Process proc in Process.GetProcessesByName("app2"))
{
proc.Kill();
}
This way the app2 processes that are still in memory can be released.
Thus based upon what I mentioned previously and what I just mentioned above, can you show me code and/or tell me what you would do to solve
the memory problem I am having?
VulpesPosted Mar 1, 2013, 7:37 PM
You could try emptying the buffer before calling Console.ReadLine() with the following line:
while(Console.KeyAvailable) Console.ReadKey(true);
If that doesn't work, I'd be inclined to forget calling Console.ReadLine() altogether bearing in mind you're killing the process with Environment.Exit(1) in the next line.
Hemant SrivastavaPosted Mar 1, 2013, 6:26 PM