Sur un système de mémoire virtuelle, l'espace d'adressage virtuel signifie que les pages virtuelles peuvent être mappées n'importe où. Vous n'avez pas besoin de grands blocs contigus de mémoire physique. Si vous rencontrez des problèmes de fragmentation de votre espace d'adressage virtuel, vous devrez peut-être utiliser une autre stratégie de gestion de la mémoire. Toutefois, la plupart des options nécessitent que votre code d'application soit conscient de la stratégie de gestion de la mémoire à un certain niveau. Je ne crois pas qu'il existe une solution rapide à ce problème - vous êtes probablement prêt pour une intervention chirurgicale assez importante pour le réparer. Aucune de ces options n'est simple à mettre en œuvre, vous devrez trouver celui qui est le plus susceptible de fonctionner dans votre cas particulier.
Les principales options que je peux voir sont: les allocateurs de mémoire personnalisés, quelque chose impliquant AWE (voir ci-dessous) ou la reconstruction de la stratégie d'allocation de mémoire dans l'application.
Option 1: répartiteurs mémoire personnalisée
répartiteurs de mémoire personnalisée ne sont pas rares dans les cercles C et C++. Vous pourriez être en mesure de mettre en œuvre quelque chose de similaire. Deux possibilités vous sont ouvertes:
Construire un allocateur de mémoire avec un mécanisme qui tente de fusionner des blocs libres adjacents en un seul bloc plus grand (vous pouvez exécuter cela comme une partie de tenter de se remettre d'une allocation de mémoire a échoué). Cela peut vous permettre de gérer la mémoire de manière transparente sans que l'application ne doive être au courant. La mise en œuvre de ce serait fastidieux et technique mais est probablement réalisable.
Le principal avantage de cette approche est qu'elle est la seule qui ne vous obligerait pas à modifier le code d'application existant. L'inconvénient est qu'il n'est pas garanti de travailler; il est toujours possible que l'opération de fusion échoue à consolider un bloc de mémoire suffisamment grand pour satisfaire la requête. L'opération de fusion peut également provoquer des pauses significatives dans la réponse de l'application pendant son exécution.
Vous devrez peut-être créer votre application de manière à compacter la structure de données. Cela vous obligerait à gérer des poignées qui prennent en charge les objets déplacés, c'est-à-dire un mécanisme d'indirection double. Je suppose qu'il y a probablement un ou un petit nombre de structures de données différentes qui causent ce problème de fragmentation, donc il peut être possible de localiser n'importe quel travail de ré-architecture au sein de votre application.
Option 2:
PAE
Windows ne les installations de soutien pour manipuler directement la MMU, et il y a deux possibilités où cela pourrait appliquer à votre application. Cela nécessiterait certainement un support architectural explicite de votre application, mais offre la possibilité d'utiliser un pool de mémoire de plus de 2 Go.
Sur les versions serveur de Windows, regardez dans PAE, qui est pris en charge par API's qui vous permet de manipuler manuellement la MMU du système et de mapper des blocs de mémoire. Cette pourrait être utile pour vous dans l'une des deux façons
Vous pouvez construire le gestionnaire de la structure de données d'une manière qui utilise ce mécanisme comme une partie intégrante de la gestion des données.
Si vous pouvez adapter les éléments de votre structure de données aux limites de la page, vous pourrez peut-être l'utiliser pour consolider la mémoire.
Cependant, cette approche vous avez besoin de repenser votre application de sorte que les références de l'objet d'informations suffisantes pour gérer le processus d'échange en explicite (peut-être une sorte de gestionnaire superposition d'un mécanisme de proxy pour les objets étant référencé à travers ce système). Cela signifie que toute solution impliquant PAE n'est pas un remplacement direct pour FastMM - vous devrez modifier l'application pour soutenir explicitement PAE.Toutefois, un mécanisme de proxy de ce type peut signifier que ce sous-système peut être relativement transparent pour les clients. Mis à part les frais généraux de gestion de l'indirection et des recouvrements (qui peuvent ou non être un problème important), les procurations pourraient être pratiquement indiscernables de l'API d'origine. Ce type d'approche fonctionnerait mieux pour un nombre relativement petit de grands objets lourds avec une interconnexion minimale - l'application canonique pour cela est la mise en cache de disque. Les proxies doivent rester dans un emplacement fixe en mémoire, les objets les plus volumineux étant accessibles via le mécanisme de superposition. YMMV.
Option 3: Correction du problème à la source
stratégie d'allocation Une possibilité est que votre objet peut être optimisé à partir du code d'application (peut-être à partir de pools d'objets alloués en vrac puis gérés dans l'application). Cela peut vous permettre de gérer la fragmentation de la mémoire à partir de votre application sans tenter de réécrire le gestionnaire de mémoire.
Encore une fois, cette approche signifie que vous devrez reconstruire des parties de votre application, et l'applicabilité de l'approche dépend vraiment de la nature de votre application. Vous seul pouvez être le juge de comment cela pourrait fonctionner.
Petite correction: Sur les versions d'OS 64 bits obtenir la plage d'adresses complète de 4 Go pour les processus 32 bits. Le processus peut ne pas être en mesure de l'utiliser (en raison des types de données signés utilisés dans les routines de gestion de la mémoire), mais la limite est différente de celle d'un système d'exploitation 32 bits. AFAIR Delphi * a * des problèmes avec cela. – mghie
Oui, Delphi utilise beaucoup de valeurs signées partout dans le RTL –