I need to execute a long-heavy process for a question out of the box. So I have divided the process in multiple subprocess. The question now, is how to release memory, before the execution of each window.
It's easier to explain with an example. Let's take a look to this pseudo-code.
1. Some earlier code to do other things
2. Do
3. Raise a Task
4. If raised-task > 1000
5. Wait all raised task to finish
6. Release Memory
7. End If
8. Wile Something not relevant
With that idea, I have developed the next method, which gets executed every time it's reached the thread limitation:
List<Task> LTask();
//It's not relevant, but this list is populate like
//var task = Task.Run(() => something());
//LTask.Add(task);
private void waitForAll()
{
//Break point 1
Task.WhenAll(LTasks).Wait();
LTasks.Clear();
LTasks = null;
GC.Collect();
GC.WaitForPendingFinalizers();
//Break point 2
LTasks = new List<Task>();
}
I expected memory gets constant (whit some variation) around some values. I mean:
- Thread limit is reached
- Snapshot of memory usage with visual studio diagnosis tools in BreakPoint 1 --> 100MB
- Snapshot of memory usage with visual studio diagnosis tools in BreakPont 2 --> 100 MB. First question, why this has not decreased? All the threads are finished and I forced Garbage Collector to execute.
Next time the limit is reached and this code is executed, if I take a snapshot again, the memory keeps increasing: 200, 300, ...
This is a capture of diagnosis tools. Odd snapshots are taken every time break point 1 is reached, and Even snapshots on break point 2.
Second question, this will continue increasing whit no limit until it throws an Out of memory Exception
?
Last question, any alternatives to solve the problem, and release the memory?
UPDATE 1: After some tests, and thanks to the comments, I have developed a test code, to dig into it. There has to be involved something else. Plase, take a look to the next piece of code. The memory continue increasing with no limit.
private List<Task> LTasks = new List<Task>();
private void manageThreadholdLimit()
{
waitForAll();
realeaseMemory();
}
private void waitForAll()
{
Task.WhenAll(LTasks).Wait();
LTasks.Clear();
LTasks = null;
}
private void realeaseMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
LTasks = new List<Task>();
}
public void Main(){
int i = 0;
while (true)
{
i++;
var task = Task.Run(() => Thread.Sleep(100));
LTasks.Add(task);
//Si hemos alcanzado el máximo de paralelismo, esperamos la conclusión
if (i % 1000 == 0) manageThreadholdLimit();
}
}