Comment optimiser la pagination pour les grandes bases de données en mémoire

J’ai une application où toute la firebase database est implémentée en mémoire en utilisant un stl-map pour chaque table de la firebase database.

Chaque élément de la stl-map est un object complexe avec des références à d’autres éléments dans les autres stl-maps.

L’application fonctionne avec une grande quantité de données, elle utilise donc plus de 500 Mo de RAM. Les clients peuvent contacter l’application et obtenir une version filtrée de la firebase database entière. Cela se fait en parcourant toute la firebase database et en trouvant des éléments pertinents pour le client.

Lorsque l’application a fonctionné pendant environ une heure, Windows 2003 SP2 commence à extraire des parties de la mémoire vive de l’application (bien qu’il y ait 16 Go de RAM sur la machine).

Une fois l’application partiellement paginée, une connexion client prend beaucoup de temps (10 minutes) car elle génère désormais une erreur de page pour chaque recherche de pointeur dans le fichier stl-map. Si le client exécute la connexion une seconde fois juste après, il est rapide (quelques secondes) car toute la mémoire est maintenant de nouveau dans la RAM.

Je peux voir qu’il est possible de dire à Windows de verrouiller la mémoire dans la RAM, mais cela est généralement recommandé uniquement pour les pilotes de périphériques, et uniquement pour les “petites” quantités de mémoire.

Je suppose qu’une solution médiocre pourrait être de parcourir la totalité de la firebase database mémoire et ainsi dire à Windows que nous sums toujours intéressés à conserver le modèle de données dans la RAM.

Je suppose qu’une autre solution pourrait être de désactiver complètement le fichier d’échange sous Windows.

Je suppose que la solution coûteuse serait une firebase database SQL, puis réécrivez l’application entière pour utiliser une couche de firebase database. Alors, espérons que le système de firebase database aura mis en place des moyens pour un access rapide.

Y a-t-il d’autres solutions plus élégantes?

Cela ressemble à une fuite de mémoire ou à un grave problème de fragmentation. Il me semble que la première étape consisterait à déterminer ce qui cause 500 Mo de données à utiliser 16 Go de RAM et à en vouloir encore plus.

Edit: Windows dispose d’un sortingmmer de jeu de travail qui tente activement de sortir les données inactives. L’idée de base est de parcourir et de marquer les pages comme étant disponibles, tout en y conservant les données (et le gestionnaire de mémoire virtuelle sait quelles sont les données qu’il contient). Cependant, si vous tentez d’accéder à cette mémoire avant de l’allouer à d’autres fins, elle sera à nouveau utilisée, ce qui l’empêchera normalement d’être renvoyée.

Si vous pensez vraiment que c’est la source de votre problème, vous pouvez indirectement contrôler le sortingmmer de jeu de travail en appelant SetProcessWorkingSetSize . Au moins dans mon expérience, cela n’est que rarement utile, mais vous vous trouvez peut-être dans une de ces situations inhabituelles où il est vraiment utile.

Comme l’a dit @Jerry Coffin, il semble que votre problème soit une fuite de mémoire. Répare ça.

Mais pour la petite histoire, aucune de vos «solutions pour les hommes pauvres» ne fonctionnerait. Du tout.

Windows publie une partie de vos données car il n’y a pas de place pour la RAM . Une boucle dans toute la firebase database de la mémoire se chargerait dans chaque octet du modèle de données, oui … ce qui provoquerait le renvoi d’autres parties. Au bout du compte, vous généreriez beaucoup de défauts de page, et la seule différence à la fin serait de savoir quelles parties de la structure de données sont extraites.

Désactiver le fichier de page? Oui, si vous pensez qu’un crash difficile est préférable à une faible performance. Windows ne diffuse pas de données de page car c’est amusant. Il le fait pour gérer des situations où il serait autrement à court de mémoire. Si vous désactivez le fichier d’échange, l’application va simplement planter lorsqu’elle renverrait des données.

Si votre dataset est vraiment si volumineux qu’il ne rentre pas dans la mémoire, je ne vois pas pourquoi une firebase database SQL serait particulièrement “coûteuse”. Contrairement à votre solution actuelle, les bases de données sont optimisées à cette fin. Ils sont destinés à gérer des ensembles de données trop volumineux pour être stockés dans la mémoire et à le faire efficacement.

Il semble que vous ayez une fuite de mémoire. Fixer ce serait la solution élégante, efficace et correcte.

Si vous ne pouvez pas le faire, alors soit

  • jeter plus de RAM sur le problème (l’application finit par utiliser 16 Go? Lancez 32 ou 64 Go à ce moment), ou
  • basculer vers un format optimisé pour un access efficace au disque (probablement une firebase database SQL)

Nous avons un problème similaire et la solution que nous avons choisie consistait à tout allouer dans un bloc de mémoire partagée. AFAIK, Windows ne lance pas cette page. Cependant, l’utilisation de stl-map ici n’est pas non plus sans importance et dépasse ce que nous avions besoin.

Nous utilisons Boost Shared Memory pour mettre en œuvre cela pour nous et cela fonctionne bien. Suivez les exemples de près et vous serez rapidement opérationnel. Boost a également Boost.MultiIndex qui fera beaucoup de ce que vous voulez.

Pour une solution SQL gratuite, avez-vous consulté Sqlite ? Ils ont une option pour exécuter en tant que firebase database en mémoire.

Bonne chance, ça sonne comme une application intéressante.

J’ai une application où toute la firebase database est implémentée en mémoire en utilisant un stl-map pour chaque table de la firebase database.

C’est le début de la fin: std :: map de STL est extrêmement inefficace en mémoire. La même chose s’applique à std :: list. Chaque élément serait atsortingbué séparément entraînant un gaspillage de mémoire assez grave. J’utilise souvent std :: vector + sort () + find () au lieu de std :: map dans les applications où cela est possible (plus de recherches que de modifications) et je sais qu’à l’avance l’utilisation de la mémoire pourrait devenir un problème.

Lorsque l’application a fonctionné pendant environ une heure, Windows 2003 SP2 commence à extraire des parties de la mémoire vive de l’application (bien qu’il y ait 16 Go de RAM sur la machine).

Difficile à dire sans savoir comment votre application est écrite. Windows a la fonctionnalité de décharger de la mémoire vive n’importe quelle mémoire des applications inactives peut être déchargée. Mais cela affecte normalement les fichiers de mappage de mémoire et similaires.

Sinon, je suggère fortement de lire la documentation de gestion de la mémoire Windows. Ce n’est pas très facile à comprendre, mais Windows dispose de toutes sortes de types de mémoire pour les applications. Je n’ai jamais eu de chance avec cela, mais probablement dans votre application utilisant std :: allocator personnalisé fonctionnerait.

Je peux croire que c’est la faute du comportement de pagefile défectueux – j’ai couru mes ordinateurs portables principalement avec le fichier d’échange désactivé depuis nt4.0. D’après mon expérience, au moins jusqu’à XP Pro, Windows intervertit les pages pour fournir l’avantage douteux d’avoir une extension vraiment très lente vers l’espace de travail maximum.

Demandez-vous quels avantages le disque dur échange avec 16 Go de mémoire vive disponible? Si votre travail le place au point d’avoir besoin de plus de mémoire virtuelle que +10 Gigs, une fois que le swap est réellement nécessaire, les processus nécessaires prendront un peu plus de temps, jusqu’à des milliers de fois plus longtemps. Sous Windows, le cache du système de fichiers indomptable semble contrarier les relations.

Maintenant, quand je suis (très) à court de travail sur mes ordinateurs portables XP, il n’y a pas d’embouteillage, l’application coupable se bloque. Un utilitaire pour suspendre les processus de chargement de mémoire avant cette heure et faire une alerte serait bien, mais il n’y a rien de tel qu’une violation, un plantage, et parfois explorer.exe tombe en panne aussi.

Pagefiles – qui a besoin d’em

—- Modifier

Étant donné l’explication de snakefoot, le problème est de remplacer la mémoire qui n’est pas utilisée pendant une période plus longue et parce que les données ne sont pas stockées en mémoire lorsque cela est nécessaire. C’est la même chose que ceci:

Puis-je dire à Windows de ne pas échanger la mémoire d’un processus particulier?

et la fonction VirtualLock devrait faire son travail:

http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx

—- Réponse précédente

Tout d’abord, vous devez faire la distinction entre les problèmes de fuite de mémoire et les problèmes de mémoire.

Si vous avez une fuite de mémoire, il serait plus difficile de convertir une application entière en SQL que de déboguer l’application.

SQL ne peut pas être plus rapide qu’une firebase database en mémoire bien conçue et spécifique à un domaine et si vous avez des bogues, il y a de fortes chances que vous en ayez également des versions SQL différentes.

S’il s’agit d’un problème de mémoire, vous devrez passer à SQL et cela semble être un bon moment.