J'ai aussi une application qui utilise autant de RAM que possible. Vous avez quelques options ici en fonction de votre scénario spécifique (tous ont des inconvénients). L'un des plus simples est de préallouer un tampon circulaire de classes (ou octets) que vous mettez en cache pour consommer tout le RAM vers l'avant. Ce n'est généralement pas préférable parce que consommer toute la RAM sur une boîte lorsque vous n'en avez pas besoin est tout simplement grossier.
Une autre façon de gérer les caches volumineux (ou d'éviter les exceptions de mémoire insuffisante) est de vérifier d'abord que la mémoire dont j'ai besoin existe avant l'allocation. Cela a l'inconvénient de devoir sérialiser les allocations de mémoire. Sinon, le temps entre la vérification de la RAM disponible et l'allocation que vous pouvez manquer de RAM.
Voici un échantillon de la meilleure façon que j'ai trouvé de le faire dans .NET:
//Wait for enough memory
var temp = new System.Diagnostics.PerformanceCounter("Memory", "Available MBytes");
long freeMemory = Convert.ToInt64(temp.NextValue()) * (long)1000000;
long neededMemory = (long)bytesToAllocate;
int attempts=1200; //two minutes
while (freeMemory < neededMemory)
{
//Signal that memory needs to be freed
Console.WriteLine("Waiting for enough free memory:. Free Memory:" + freeMemory + " Needed Memory(MB):" + neededMemory);
System.Threading.Thread.Sleep(100);
freeMemory = Convert.ToInt64(temp.NextValue()) * (long)1000000;
--attempts;
if (0 == attempts)
throw new OutOfMemoryException("Could not get enough free memory. File:" + Path.GetFileName(wavFileURL));
}
//Try and allocate the memory we need.
De plus, une fois que je suis à l'intérieur de la boucle while je signale que de la mémoire doit être libéré (en fonction de votre application). Remarque: j'ai essayé de simplifier le code en utilisant une instruction Sleep, mais finalement vous voudriez un certain type d'opération non-polling si possible. Je ne suis pas sûr sur les spécificités de votre application, mais si vous êtes multithread, ou exécutez plusieurs exécutables différents, il peut être préférable de sérialiser cette vérification de la mémoire lorsque la mémoire allouée à la mémoire cache. Si c'est le cas, j'utilise un sémaphore pour m'assurer qu'un seul thread et/ou processus peut allouer de la RAM si nécessaire. Semblable à ceci:
Semaphore namedSemaphore = new Semaphore(1, 1, "MemoryAllocationSemaphore"); //named semaphores are cross process
if (bytesToAllocate > 2000000) //if we need less than 2MB then dont bother locking.
{
if (!namedSemaphore.WaitOne((int)TimeSpan.FromMinutes(15).TotalMilliseconds))
{
throw new TimeoutException("Waited over 15 minutes for aquiring memory allocation semaphore");
}
}
Puis un peu plus tard cette appel:
namedSemaphore.Release();
dans un bloc finally pour libérer le sémaphores.
Une autre option consiste à utiliser un verrou d'écriture unique à plusieurs lecteurs.Pour avoir plusieurs threads tirant des données du cache (comme la classe ReaderWriterLock). Cela a l'avantage que, pendant que vous écrivez, vous pouvez vérifier la pression et le nettoyage de la mémoire, puis ajouter davantage au cache, tout en conservant plusieurs threads traitant les données. L'inconvénient est bien sûr que le goulot d'étranglement de l'obtention de données dans le cache provient d'un seul point fixe.
cochez cette réponse: http://stackoverflow.com/a/1248141/941243 – Chris