Manage the number of class instances

I have a class B from which I create a huge number of instances to speed up some searches in the optimization problem. The number gets so big that I often do OutOfMemory-Exceptions. As a workaround, I reduce the number of instances every x seconds, but I would like to do something more sensible. For this, I would like to know:

  • What is a good way to manage the number of live instances (created and not yet collected garbage)

  • More technical: how can I evaluate the RAM that I should use (say) about half of it for my instances?

+4
source share
5 answers

First of all, I will try to minimize the memory size of each individual object. Since you create a huge number of objects, it is likely that many of them have similar properties, which makes them an ideal candidate for a fly. A classic example according to Wikipedia article is word processing:

A classic example of using the flyweight template is a data structure for graphically representing characters in a word processor. It might be desirable to have a glyph object for each character in the document containing its font outline, font metrics, and other formatting data, but this would be hundreds or thousands of bytes for each character. Instead, for each character, there may be a reference to a glyph offset object that is shared by each instance of the same character in the document; only the position of each character (in the document and / or on the page) should be stored inside.

As a second step, I would evaluate the size of one object. I emphasize evaluation in this context, because getting the actual size is not so easy in C # . This estimate can then be used to set the maximum number of N objects that can be safely created without encountering an OutOfMemoryException .

You can use this information by tracking how many objects are (approximately) alive, updating the object counter each time an object is created or destroyed, for example.

 class Foo { private static NumberOfInstances = 0; public Foo() { NumberOfInstances++; } ~Foo() { NumberOfInstances--; } } 

If the thread safety issue is a problem, this implementation, of course, needs to be clarified a bit.

Edit: As Mike noted in his comment, implementing this through a finalizer can lead to serious performance issues in this context. Therefore, it would be better to implement IDisposable and decrement in the Dispose operation. However, this has the disadvantage that you can forget about deleting the object. However, I doubt that this will be a serious problem in your case.

+5
source

I do not know the answer to the second question, but the answer to the first question may be as follows:

+2
source

It looks like you would like to keep as much as possible of the already calculated data for access to them later. Perhaps the MemoryCache class introduced in .NET 4.0 might be useful in your case.

You can do something like this:

 var cache = new MemoryCache("PathCache", new NameValueCollection() { { "CacheMemoryLimitMegabytes", "256" }, // max 256 MB { "PhysicalMemoryLimit", "50" } // max 50% of RAM }); // cache an item cache["MyPath"] = "..."; // check, whether the cache contains an item if (cache.Contains("MyPath")) { // cache hit! var cachedPath = cache["MyPath"]; } // ensure cache is released somewhere in your code cache.Dispose(); 
+2
source

Each node extension should request data and not store all object data in memory, just save the defining parameters with each node. Selecting node displays the data from the query.

0
source

You can use the factory template to create your instances and thus track them and manage you memmory

0
source

Source: https://habr.com/ru/post/1496433/


All Articles