Garbage Collection bug?

  • Thread starter Thread starter Anderas Broman
  • Start date Start date
A

Anderas Broman

Hi,

I am developing a C# application for Windows CE. I have about 88 MB free
memory on my device, but I got some strange out of memory exceptions so I
decided to write a simple memory testing app that allocates memory until
this is no longer possible. This application can however only allocate about
24 MB before the memory allocation fails. (GC.GetTotalMemory)

Why is that?

Regards,
Andreas Broman

The memory allocation part of my test app:
*******************
using System;
using System.Collections;

namespace MemTestApp
{
public class AllocationManager
{
private Stack theMemBlocks = new Stack();

public void AllocateMemory( int size)
{
byte[] block = new byte[size];
theMemBlocks.Push( block);
}

public void DeallocateAllMemory()
{
while (theMemBlocks.Count > 0)
{
byte[] block = (byte[])theMemBlocks.Pop();
}
}

}
}
 
1. Does GC know about this 32 MB limitation?
My application throws an exception (due to insufficent memory) after a
number of iterations in a loop, but if I use GC.Collect(), the application
works just fine.

Thus: It seems like GC does not automatically detect the insufficent memory
since it does not run automatically.
(The exception is acually thrown when running a query on SQL Server CE 2.0.)

2. I still don't get why the test app described below fails. 24 MB is quite
far from the 32 MB limit...

"Alex Yakhnin [MVP]" wrote in message
Each process is restricted to its own 32MB address space in Windows CE OS.

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

in message
Hi,

I am developing a C# application for Windows CE. I have about 88 MB free
memory on my device, but I got some strange out of memory exceptions so I
decided to write a simple memory testing app that allocates memory until
this is no longer possible. This application can however only allocate about
24 MB before the memory allocation fails. (GC.GetTotalMemory)

Why is that?

Regards,
Andreas Broman

The memory allocation part of my test app:
*******************
using System;
using System.Collections;

namespace MemTestApp
{
public class AllocationManager
{
private Stack theMemBlocks = new Stack();

public void AllocateMemory( int size)
{
byte[] block = new byte[size];
theMemBlocks.Push( block);
}

public void DeallocateAllMemory()
{
while (theMemBlocks.Count > 0)
{
byte[] block = (byte[])theMemBlocks.Pop();
}
}

}
}
 
So you continually allocate memory until you get an OutOfMemoryException and
you don't understand why? I would expect this behavior. How should the GC
"fix" it? It can't collect memory that's in use.

As for the 24/32MB difference, CE has 32MB process slots. That means
everything for a process is limited to 32MB, not just the amount of possible
heap space. The app resides in the slot, any DLLs it uses are in the slot.
If you've uncompressed the CF and SQL CE into your slot, that's a good chunk
right there.

-Chris


Andreas Broman said:
1. Does GC know about this 32 MB limitation?
My application throws an exception (due to insufficent memory) after a
number of iterations in a loop, but if I use GC.Collect(), the application
works just fine.

Thus: It seems like GC does not automatically detect the insufficent memory
since it does not run automatically.
(The exception is acually thrown when running a query on SQL Server CE 2.0.)

2. I still don't get why the test app described below fails. 24 MB is quite
far from the 32 MB limit...

"Alex Yakhnin [MVP]" wrote in message
Each process is restricted to its own 32MB address space in Windows CE OS.

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

in message
so
I
decided to write a simple memory testing app that allocates memory until
this is no longer possible. This application can however only allocate about
24 MB before the memory allocation fails. (GC.GetTotalMemory)

Why is that?

Regards,
Andreas Broman

The memory allocation part of my test app:
*******************
using System;
using System.Collections;

namespace MemTestApp
{
public class AllocationManager
{
private Stack theMemBlocks = new Stack();

public void AllocateMemory( int size)
{
byte[] block = new byte[size];
theMemBlocks.Push( block);
}

public void DeallocateAllMemory()
{
while (theMemBlocks.Count > 0)
{
byte[] block = (byte[])theMemBlocks.Pop();
}
}

}
}
 
No, I am not allocating memory until I get an OutOfMemoryException (in my
real app that is - I do in the simple test app for question #2)

I am running a loop in which I run a query on a table in a database (and I
am ".Close()"-ing the reader).
When I throw in a "GC.Collect()" call in the loop, the application consumes
at most 1 MB of memory and is working just fine, but without this forced
garbage collection, the application consumes memory until it gets an
SqlCeDatabase exception with an error code indicating that there is not
enough memory available.
The memory allocation behavior seems OK to me (allocate a lot to gain speed
at the moment, then take care of the garbage later), but I would expect the
garbage collector to run before I get the SqlCeDatabase exception...
Any ideas why it does not?


Thanks for answer #2!

/Andreas


Chris Tacke said:
So you continually allocate memory until you get an OutOfMemoryException and
you don't understand why? I would expect this behavior. How should the GC
"fix" it? It can't collect memory that's in use.

As for the 24/32MB difference, CE has 32MB process slots. That means
everything for a process is limited to 32MB, not just the amount of possible
heap space. The app resides in the slot, any DLLs it uses are in the slot.
If you've uncompressed the CF and SQL CE into your slot, that's a good chunk
right there.

-Chris


Andreas Broman said:
1. Does GC know about this 32 MB limitation?
My application throws an exception (due to insufficent memory) after a
number of iterations in a loop, but if I use GC.Collect(), the application
works just fine.

Thus: It seems like GC does not automatically detect the insufficent memory
since it does not run automatically.
(The exception is acually thrown when running a query on SQL Server CE 2.0.)

2. I still don't get why the test app described below fails. 24 MB is quite
far from the 32 MB limit...

"Alex Yakhnin [MVP]" wrote in message
Each process is restricted to its own 32MB address space in Windows CE OS.

--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

in message
Hi,

I am developing a C# application for Windows CE. I have about 88 MB free
memory on my device, but I got some strange out of memory exceptions
so
I
decided to write a simple memory testing app that allocates memory until
this is no longer possible. This application can however only allocate
about
24 MB before the memory allocation fails. (GC.GetTotalMemory)

Why is that?

Regards,
Andreas Broman

The memory allocation part of my test app:
*******************
using System;
using System.Collections;

namespace MemTestApp
{
public class AllocationManager
{
private Stack theMemBlocks = new Stack();

public void AllocateMemory( int size)
{
byte[] block = new byte[size];
theMemBlocks.Push( block);
}

public void DeallocateAllMemory()
{
while (theMemBlocks.Count > 0)
{
byte[] block = (byte[])theMemBlocks.Pop();
}
}

}
}
 
Regrettably, the garbage collector is not aware of any memory allocations
that are made by unmanaged components such as SqlCe. For each each small
managed query object you create, there is a large amount of memory
allocated by SqlCe and associated with that object that the Compact
Framework garbage collector isn't aware of. Rather than using GC.Collect to
force the memory to be freed, it would be more efficient to either reuse
the query rather than creating a new one or closing it. Hopefully that will
help.

--------------------
From: "Andreas Broman" <[email protected]>
References: <[email protected]>
<#[email protected]>
Subject: Re: Garbage Collection bug?
Date: Wed, 28 Apr 2004 16:49:28 +0200

No, I am not allocating memory until I get an OutOfMemoryException (in my
real app that is - I do in the simple test app for question #2)

I am running a loop in which I run a query on a table in a database (and I
am ".Close()"-ing the reader).
When I throw in a "GC.Collect()" call in the loop, the application consumes
at most 1 MB of memory and is working just fine, but without this forced
garbage collection, the application consumes memory until it gets an
SqlCeDatabase exception with an error code indicating that there is not
enough memory available.
The memory allocation behavior seems OK to me (allocate a lot to gain speed
at the moment, then take care of the garbage later), but I would expect the
garbage collector to run before I get the SqlCeDatabase exception...
Any ideas why it does not?


Thanks for answer #2!

/Andreas


Chris Tacke said:
So you continually allocate memory until you get an OutOfMemoryException and
you don't understand why? I would expect this behavior. How should the GC
"fix" it? It can't collect memory that's in use.

As for the 24/32MB difference, CE has 32MB process slots. That means
everything for a process is limited to 32MB, not just the amount of possible
heap space. The app resides in the slot, any DLLs it uses are in the slot.
If you've uncompressed the CF and SQL CE into your slot, that's a good chunk
right there.

-Chris


Andreas Broman said:
1. Does GC know about this 32 MB limitation?
My application throws an exception (due to insufficent memory) after a
number of iterations in a loop, but if I use GC.Collect(), the application
works just fine.

Thus: It seems like GC does not automatically detect the insufficent memory
since it does not run automatically.
(The exception is acually thrown when running a query on SQL Server CE 2.0.)

2. I still don't get why the test app described below fails. 24 MB is quite
far from the 32 MB limit...

"Alex Yakhnin [MVP]" wrote in message
Each process is restricted to its own 32MB address space in Windows
CE
OS.
--
Alex Yakhnin .NET CF MVP
www.intelliprog.com | www.opennetcf.org

in message
Hi,

I am developing a C# application for Windows CE. I have about 88 MB free
memory on my device, but I got some strange out of memory
exceptions
so
I
decided to write a simple memory testing app that allocates memory until
this is no longer possible. This application can however only allocate
about
24 MB before the memory allocation fails. (GC.GetTotalMemory)

Why is that?

Regards,
Andreas Broman

The memory allocation part of my test app:
*******************
using System;
using System.Collections;

namespace MemTestApp
{
public class AllocationManager
{
private Stack theMemBlocks = new Stack();

public void AllocateMemory( int size)
{
byte[] block = new byte[size];
theMemBlocks.Push( block);
}

public void DeallocateAllMemory()
{
while (theMemBlocks.Count > 0)
{
byte[] block = (byte[])theMemBlocks.Pop();
}
}

}
}

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top