We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Hashtable

We're running into an occasional exception when performing a ResizeToFit on columns. This is with very large virtual grids (version 3.3.0.0).

The root of the exception (and InvalidOperationException from with a "Load factor too high" message) is Hashtable.Insert() which is coming from GridVolatileData's SetItem() method. It appears you guys actually had some handling for the exception that does a GC.Collect and retries to set the data[] indexer.

In our case, it's clearly not an out of memory problem. From looking at Hashtable in Reflector, it appears that it's having trouble finding an empty bucket for an item after a hash collision, even though there might be say 521 buckets total and only 15 buckets occupied.

Do you guys have any additional information on this issue? We're concurrently talking to IBM about this because it seems like it's probably a Hashtable issue, but I thought it would be worthwhile checking with you guys as well.

Thanks.

Pete Davis

3 Replies

HA haneefm Syncfusion Team July 25, 2007 05:45 PM UTC

Hi Pete,

Below is a forum thread that discuss with the similar issue.
http://www.syncfusion.com/support/forums/message.aspx?&MessageID=32767

When you use the debug builds for Essential Grid, you will get a trace message that indicates how many items are in the volatile data cache.

Here is the code for SetItem



public void SetItem(GridCellPos cell, GridStyleInfo style)
{
try
{
if (data.Count >= forceGcCollect)
GC.Collect();
#if DEB
if (data.Count > maxDataCount)
{
Console.WriteLine("VolatileData HashTable: " + data.Count.ToString());
maxDataCount = data.Count + data.Count/10; // let's just show a Trace statement for larger increases ...
}
#endif
data[cell] = new WeakReference(style);
}
catch (InvalidOperationException ex)
{
// should be InvalidOperation_HashInsertFailed=Hashtable insert failed. Load factor too high.
TraceUtil.TraceExceptionCatched(ex);
Trace.WriteLine("Detected too many items in volatile date hashtable. You should set GridVolatileData.forceGcCollect to a value below " + data.Count.ToString());
TraceUtil.TraceCurrentMethodInfo("Hashtable count: ", data.Count);
GC.Collect();
TraceUtil.TraceCurrentMethodInfo("Hashtable count after GC.Collect: ", data.Count);
data[cell] = new WeakReference(style);
}
}



The exception itsself is handled by an exception handler and resolved when it happens. Basically what I need to do is force a call to GC.Collect.

If you have source code than you could change the value for forceGCCollect to be less than what is written out.

The error can happen in rare cases when more items are cached than the Hashtable can hold. This is when you do a extensive operation and GC is not called for a while or when you keep references to the style objects and therefore the GC can not release the objects.

Try checking this issue in any one of our latest version. Please refer the link below for the download details of the latest version.
http://www.syncfusion.com/downloads/latestversion/default.aspx

FYI, we have added many new features and samples to our latest version. Performance of gridgroupingcontrol has been increased.

Best regards,
Haneef


PD Pete Davis July 25, 2007 05:56 PM UTC

Haneef,

Thanks for the information, but this does not appear to be the case. As I said before, the hashtable has 521 buckets and only, maybe 15 or so are occupied.

The handler does the GC.Collect and retries, but we get the exception again on the retry.

This doesn't appear to relate to the amount of memory used. As the ResizeToFit() operation is taking place, it can happen as soon as a few seconds into it or as long as 30 minutes into it (like I said, it's a huge table). The memory footprint doesn't appear to be an issue and it appears to happen more or less at random.

One thing we did note is that GridModel.Dispose(bool disposing) appears to be releasing managed objects regardless of whether or not disposing is true or false (there's no check made) and one of the things it does is set data = null.

We have a great number of grids in our app. Could this be related.

As far as using a more recent version, that's not possible. We have several classes derived from these controls and our product is already being shipped.

Pete


PD Pete Davis July 25, 2007 09:02 PM UTC

Haneef,

We believe we may have tracked down the problem, but we're not precisely sure what the fix is.

The finalizer for GridStyleInfoIdentity is as follows:

~GridStyleInfoIdentity()
{
if (!offLine && data != null)
((IGridVolatileData) data).ResetItem(cellPos);
}


ResetItem() then goes on to remove the item from the hashtable. This is bad. The finalizer is called from a non-GUI thread and the Hashtable access isn't synchronized to prevent multiple threads from modifying it. Therefore, it's possible (and we believe this is in fact happening) that the finalizer thread could be removing an item concurrently while the ResizeToFit call is iterating through them, corrupting the Hashtable.

The problem is, we're not exactly sure how to fix this. We'd appreciate any ideas you guys may have.

Loader.
Live Chat Icon For mobile
Up arrow icon