Garbage collector and multiple threads

  • Thread starter Thread starter Pawan Singh
  • Start date Start date
P

Pawan Singh

IS there a way to tell GC in .Net to not suspend a particular thread while
garbage collecting (obviously this would also require telling the GC to not
touch objects which this thread has reference to). This will help in making
some of my threads do things on time (I require some threads to do things
within 25-100ms of a specified time). This problem is causing my threads to
execute sometimes beyond 600 milliseconds of specified time because it is
being hijacked by the GC.
 
Pawan Singh said:
This problem is causing my threads to
execute sometimes beyond 600 milliseconds of specified time because it is
being hijacked by the GC.

I don't really know about preventing the GC from doing its work (i guess
that it is not possible to stop the GC as it would defeat the whole point of
having a GC) but if you have strong time constraints as the one you've
presented here, i advise you to program your application in a real-time
environment and not on Windows with .NET. Even if you can stop the GC,
Windows or the .NET runtime can anyway suspend your thread at any time to
give some processor time to another. Which will make your thread to miss its
deadline.

To stop the GC, you could maybe write the code executed in your thread in
unmanaged C++. The GC would not mess around with it.
 
Unfortunately, the project has to be done in .Net. That is why I wanted to
suspend GC for short duration. I do not want to stop it completely - I want
it not to run for some controlled time or "spare my thread and its objects"
when it wants to run. That would solve my problem.

Thanks
-Pawan
 
No, it wouldn't. A thread context switch or a tight loop somewhere would
cause the same havoc as well.

If memory serves me correct, i believe there is a gc.suspend call you can
make in your thread
 
Pawan Singh said:
Unfortunately, the project has to be done in .Net. That is why I wanted to
suspend GC for short duration. I do not want to stop it completely - I want
it not to run for some controlled time or "spare my thread and its objects"
when it wants to run. That would solve my problem.

The only way to prevent Garbage Collection is to create no garbage. Garbage
Collection is always triggered by a request to allocate an object on the
managed heap. If your application gets to a state where it creates no
additional heap objects, then no Garbage Collections will occur.

While not imposible, achieving this is quite tricky and requires you to
closely control object creation and allocation in the whole process in ways
which severly constrain your programming. For instance you must replace
reference objects with value objects, recycle reference objects instead of
allocating new ones, and refrain from invoking any .net framework methods
without verifing that they don't create temporary heap objects (which is
never documented, and never guaranteed not to change).

In short, your program would be so contorted by the no-garbage requirement
that you would be better off writing in unmanaged C++.

The only other thing I can think of is that if you allocate little enough
heap memory, you might get your GC times down to short enough not to care
when GC runs. Add to that manual GC.Collect() when you know you have time,
and you might squeak by.

David
 
If someone is giving you requirements to run a process in 25-100ms AND it
has to be done in .NET, run away. They are obviously not very smart and will
likely continue to give you conflicting requirements that will eventually
turn your hair gray. ;-)
 
Hi Pawan,

The process of garbage collection involves reclaiming memory and then
compacting the managed heap. Compacting the heap means changing the object
references to point to new addresses.While this is happening, it is obvious
that no thread should access these objects as the references may become
invalid after collection. Hence all threads are suspended till collection
process is done.

If you really want to perform a mission critical operation on a thread,
considering boosting the thread priority. It does not make sense to spare a
thread alone from collection as all threads share the same managed heap.
 
My problem is that boosting the thread priority does not achieve anything.

Can Microsoft provide what is the upper bound on delay due to garbage
collection assuming that CPU utilization is minimal?

What I am noticing is that if you want a thread to execute at a particular
time, thread.sleep(xxx) can miss its interval by more than 1 second if
garbage collector is busy. I would have thought that it will be of the order
of 10-50 milliseconds.

Also I am noticing is that garbage collector is using at least 28% CPU in my
application as it needs to create a lot of small objects.

-Pawan

Manoj G said:
Hi Pawan,

The process of garbage collection involves reclaiming memory and then
compacting the managed heap. Compacting the heap means changing the object
references to point to new addresses.While this is happening, it is obvious
that no thread should access these objects as the references may become
invalid after collection. Hence all threads are suspended till collection
process is done.

If you really want to perform a mission critical operation on a thread,
considering boosting the thread priority. It does not make sense to spare a
thread alone from collection as all threads share the same managed heap.

--
HTH,
Manoj G
[MVP , Visual Developer - Visual Basic ]
http://msmvps.com/manoj/

Pawan Singh said:
IS there a way to tell GC in .Net to not suspend a particular thread while
garbage collecting (obviously this would also require telling the GC to not
touch objects which this thread has reference to). This will help in making
some of my threads do things on time (I require some threads to do things
within 25-100ms of a specified time). This problem is causing my threads to
execute sometimes beyond 600 milliseconds of specified time because it is
being hijacked by the GC.
 
Pawan Singh said:
My problem is that boosting the thread priority does not achieve anything.

Can Microsoft provide what is the upper bound on delay due to garbage
collection assuming that CPU utilization is minimal?

What I am noticing is that if you want a thread to execute at a particular
time, thread.sleep(xxx) can miss its interval by more than 1 second if
garbage collector is busy. I would have thought that it will be of the order
of 10-50 milliseconds.

Also I am noticing is that garbage collector is using at least 28% CPU in my
application as it needs to create a lot of small objects.

You keep asking for something which you will not receive. .Net is not
suitable for realtime development.

Perhaps it would be possible for your application to be separated into a
realtime portion and one or more .Net portions. The .Net portions could, for
example, produce input for the realtime portion and could consume the output
of the realtime portion.
 
David Browne said:
The only way to prevent Garbage Collection is to create no garbage. Garbage
Collection is always triggered by a request to allocate an object on the
managed heap. If your application gets to a state where it creates no
additional heap objects, then no Garbage Collections will occur.

While not imposible, achieving this is quite tricky and requires you to
closely control object creation and allocation in the whole process in ways
which severly constrain your programming. For instance you must replace
reference objects with value objects, recycle reference objects instead of
allocating new ones, and refrain from invoking any .net framework methods
without verifing that they don't create temporary heap objects (which is
never documented, and never guaranteed not to change).

In short, your program would be so contorted by the no-garbage requirement
that you would be better off writing in unmanaged C++.

Do AppDomains have separate heaps, and so separate garbage collectors? If
so, you could potentially do your minimal allocation stuff in a separate
domain.

Even if that is the case, I'd still agree that .NET probably isn't the best
platform for real-time programming. Might we ask why the project must be
done in .NET? Why can't it be mixed mode?
 
Stu said:
Do AppDomains have separate heaps, and so separate garbage collectors? If
so, you could potentially do your minimal allocation stuff in a separate
domain.

Even if that is the case, I'd still agree that .NET probably isn't the best
platform for real-time programming. Might we ask why the project must be
done in .NET? Why can't it be mixed mode?

If you create a native dll to do the 'time critical' stuff in separate
threads, won't the GC still suspend those threads when running? If so,
then you have to create it as a native process (or service) but then
there may be lots of over-head transferring data from one process to the
other.

Or are threads created from native code excluded from being suspended by
the GC? If so, then a native DLL that exports its classes to be used by
a managed C++ app would be the easiest way to go IMHO.

Cheers

Russell
 
Back
Top