-1

If I create and array without initialization the program uses only a few MB of memory to save the reference. For example like this:

int[] arr = new int[1000000000];

Later if I initialize the elements of array the memory usage goes up by the full array amount.

The memory usage is lower if I initialize only a part of array.

for (int i = 0; i < arr.Length; i++) // Full memory usage, length * sizeof(int)
{
      arr[i] = i;
}
----------------------------------------------------------
for (int i = 0; i < arr.Length/2; i++) // Only ~half memory usage, (length / 2) * sizeof(int)
{
      arr[i] = i;
}

Now I need to use my full initialized array to create an data structure and then reduce its size by keeping every N element. Because the array is very big reducing its size can save several GB. The missing elements can be calculated from the remaining ones and created data structure. Its a trading calculation time for memory usage.

Now to the question: Is it possible in C# to release some memory from array after the array is fully initialized?

I have tried to set every Nth element to zero but the memory usage is still the same.

Kostej
  • 154
  • 1
  • 9
  • I need to keep the size the same so I know which elements I need to recalculate (their value is 'blank' ) If i keep every third element from array of length 8 the array would look like this `[1,-,-,4,-,-,7,-]` and save memory by 'deleting' elements – Kostej Oct 26 '22 at 19:31
  • Why you don't want to use List? – Lonli-Lokli Oct 26 '22 at 19:48
  • 1
    Computer memory doesn't work that way. When you assign values to half of the elements, the half that you didn't assign are still there. They can't be compressed. There are data structures known as "sparse arrays", but either they're not arrays (in the contiguous sense, as they're more like dictionaries) or they require *more* memory to track which elements are "used" vs. "unused". – madreflection Oct 26 '22 at 19:53
  • 3
    There is no such thing as a "blank" value in an Int32 array. All values are initialized to 0. – gunr2171 Oct 26 '22 at 19:53
  • There are millions of possibilities to save memory allocation. It depends on what you want to achieve. If you prefer low memory over time you could store values on your harddrive or a database. If you dont like using one of those, you could try out Span. Here is a small article: https://blog.ndepend.com/improve-c-code-performance-with-spant/ – Sebastian Siemens Oct 26 '22 at 19:57

2 Answers2

1

Although Array.Resize() sounds like an option, in reality wouldn't satisfy your question. Your question is: How can I release RAM? Am I correct? If so, using Array.Resize() will only make it worse, because in reality it creates a new array, leaving the source untouched, so in reality this consumes even more RAM.

In the safe space of .Net, I don't think you can immediately drop the RAM. I think you will just have to create a final list of numbers and drop all references to the original array and wait for the garbage collector to do its job, or see if you can collect faster by calling GC.Collect().

In the unsafe space, however, you can control your RAM usage.

I will stop here for now because I just read an incoming comment from you stating that you need to delete the space but keep the size. You are using an array of a primitive data type. This array, once initialized, cannot be deleted, regardless of being in a safe or unsafe context.

In your case, I would then use a dictionary to save the remaining values and drop the entire original array. Line in your comment example, where you have 8 elements and you are conserving every 3rd element. Your dictionary will have 3 elements, then you drop the entire original array. The dictionary's key will tell you the array's original index, while its value will give you, well, the value contained in that position.

José Ramírez
  • 872
  • 5
  • 7
0

What if you initialize a second array

int[] arrCopy = new int[1000000000];

Copy the first array into the second

Array.Copy(arr, arrCopy, 1000000000);

Re-initialize the first array

arr = new int[1000000000];

Iterate over the second array and store every Nth value into the first

for (int i = 0 ; i < 1000000000; i += N){
    arr[i] = i;
}

Re-initialize the second array

arrCopy = new int[1000000000];

mmartinez04
  • 323
  • 1
  • 1
  • 4