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();
}
}
