Getting Available Continuous Memory

I need to generate large bold large images, something like 15000x3000. I generate these images using GDI +, class Bitmap .

Of course, the generation failed from time to time because there is no more memory to create an instance of Bitmap. My goal is to inform my user of the maximum size of the image that they are allowed to generate.

The message should look like this:

You tried to create an image of size 15000x3000, but not enough memory. The maximum size is 10000x3000 or 15000x1000.

The idea of ​​creating a message is this:

public bool CanCreateBitmap(Size size, out string message) { long availableMemory = this.GetAvailableContiguousMemory(); long bytesRequiered = (long)size.Width * size.Height * 32; if (availableMemory < bytesRequiered) { var sizeProposal1 = new Size(size.Width, (int)(availableMemory / (32 * size.Width))); var sizeProposal2 = new Size((int)(availableMemory / (32 * size.Height)), size.Height); message = string.Format("You tried to generate an image of size {0}, but there is not enough memory." + Environment.NewLine + "The maximum size available is {1}, or {2}." , size, sizeProposal1, sizeProposal2); return false; } else { message = ""; return true; } } 

But I do not have code for the GetAvailableContiguousMemory() function.

Is there a way to get contiguous memory in .Net?
Am I asking the right question to achieve my goal?

+4
source share
2 answers

There is no such function, because the question "How much memory can I allocate" contains a race condition. Suppose that there is a function that you need, and you call it, and it tells you that there is a huge amount of available memory. You associate this with the user, the user decides the size of the image, and then you get the actual selection of the image. But some other process took up half the available memory at that time, and now your call is interrupted with an OutOfMemoryException.

A similar problem occurs when streaming media over TCP / IP. You would like to start streaming video, but it requires quite a lot of network bandwidth, and you want to be sure that this bandwidth will be available in a couple of minutes, since it would be counterproductive to start the video stream only to get stuck when playback reaches two thirds of the length of the video. Now this problem has been resolved by reserving network resources during the confirmation phase - even if you are not using bandwidth right now (video streaming has not started yet).

Well, you can try to achieve a similar effect with some obscure Windows API calls. Try to start the exploration from the VirtualAlloc function . However, I would not recommend that you go along this path, because your application, even if you make it functional, may be unstable or unreliable or affect other processes in the system. In particular, these Windows APIs are initially used in C ++, and you work with a managed heap in .NET. I have not tried this approach and cannot predict the result (but I would like to hear results from you if you succeed!).

What you are asking is a design decision. I would also recommend the dandan78 approach - letting the user select the image size, try to create it and report an error if the attempt failed. Users will eventually get used to their computer capabilities and will not often push the system beyond.

EDIT: Another thing you should keep in mind: there is no such thing as “available continuous memory”. The operating system provides you with virtual memory pages. After that, these pages are loaded into memory. If you ask for a lot of memory, you will get a bunch of pages that will be assigned sequential addresses in the virtual memory space, and that you will get the impression that the memory is contiguous. But you usually have non-contiguous memory cells returned by the new operator, because the memory manager simply returns the first available slot in the managed heap. I know that these notes are not suitable for this question, but, of course, it does not hurt to preserve memory management strategies in situations such as this.

+3
source

These notifications are a bandage that does not actually help the user. They really wanted to create such a large raster image, and arbitrarily smaller is not what they wanted. If you still want to do this, you will need to output VirtualQuery to go through the virtual address space and find fragments that are not yet displayed.

These days there is no more sense in this problem, change the setting of the Target Platform Target platform to AnyCPU so that your program can use the heaps of virtual memory available in the 64-bit operating system.

+3
source

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


All Articles