Quelle quantité de mémoire de votre programme prend? (FastMM vs Borland MM)

StackOverflow https://stackoverflow.com/questions/4499260

  •  12-10-2019
  •  | 
  •  

Question

J'ai vu récemment un comportement étrange dans mon programme. Après avoir créé de grandes quantités d'objets (500 Mo de RAM), puis de les libérer, l'empreinte mémoire du programme ne retourne pas à sa taille d'origine. Il montre encore une empreinte de 160MB (set de travail privé).

Comportement normal?

Le gestionnaire de mémoire de Borland ne se comporte pas comme ça, donc si possible confirmer s'il vous plaît (ou infirmes) c'est un comportement normal pour FastMM: Si vous avez un programme très pratique dans lequel vous créez un enfant MDI assez complexe (contenant plusieurs contrôles / objets ), pouvez-vous créer dans une boucle de 250 cas de cet enfant de MDI en mémoire (en même temps), puis les libérer tous et vérifier l'empreinte mémoire. S'il vous plaît assurez-vous que vous consommez au moins 200-300MB ou RAM avec ces Childs MDI.

En particulier ceux qui utilisent encore Delphi 7 peut voir la différence par FastMM invalidante temporaire.

Merci


Si quelqu'un est intéressé, surtout si vous voulez une preuve ce n'est pas une fuite de mémoire (je l'espère n'est pas une fuite de mem dans mon code - ce qui est aussi l'un des points de ce poste: pour vérifier si elle est ma faute), voici les discussions originales:

Mon programme ne libère la mémoire de retour. Pourquoi?
Comment convaincre le gestionnaire de mémoire pour libérer la mémoire inutilisée

Était-ce utile?

La solution 5

RESOLU

Pour confirmer que ce comportement est généré par FastMM (comme suggéré par Barry Kelly) J'ai créé un deuxième programme qui a alloué beaucoup de RAM. Dès que Windows a manqué de RAM, mon utilisation de la mémoire du programme est revenu à sa valeur d'origine.

Problème résolu. Un grand merci à Barry Kelly, la seule personne qui pointait vers le « problème » réel.

Autres conseils

IIRC, le gestionnaire de mémoire Delphi ne retourne pas immédiatement la mémoire free'd à l'OS.

La mémoire est allouée en morceaux de petites, moyennes et grandes tailles, blocs appelés. Ces blocs sont conservés pendant un certain temps après leur contenu ont été disposés à les avoir readyly disponibles lorsqu'une autre allocation est demandée par la suite.

Cela limite le montant des appels système requis pour l'attribution de plusieurs objets successive, et aide à éviter la fragmentation tas.

infirmer: Delphi 2007, gestionnaire de mémoire par défaut (variation doit être FastMM). Plusieurs tests sur des objets lourds:

  1. Mémoire initiale 2Mb, 30Mo de mémoire de pointe, la mémoire finale 4Mo.
  2. Mémoire initiale 2Mb, pic 1gb, 5.5Mb mémoire final.

Cher autel, je suis ébloui à quel point le point de vous dans vos suppositions et comment vous ne l'écoutez pas ce que les gens vous ont dit de nombreuses fois.

Soit de l'ensemble des choses droites. Gestion de la mémoire 101. S'il vous plaît lire attentivement.

Lorsque vous allouez la mémoire à Delphes, il y a deux gestionnaires de mémoire impliqués.

Gestionnaire de mémoire système

Le premier est un gestionnaire de mémoire système. Celui-ci est intégré dans Windows et il donne la mémoire dans les pages de 4 Ko de taille.

Mais il ne vous donne pas toujours la mémoire dans la RAM (ou mémoire physique). Vos données peuvent être conservées sur le disque dur, et relues à chaque fois que vous avez besoin d'y accéder. Ceci est terriblement lent.

En d'autres termes, imaginez que vous avez 512 Mo de mémoire physique. Vous exécutez deux programmes, chacun demandant 1Go de mémoire. Qu'est-ce que OS faire?

Il accorde aux deux demandes. Les deux applications se 1Go de mémoire chacun. Les deux pensent toute la mémoire est « en mémoire ». Mais en fait, que 512 Mo peut être conservé dans la mémoire vive. Le reste est stocké dans le fichier de page, bien que votre application ne sait pas. Il fonctionne lent.

Taille du jeu de travail

Maintenant, ce qui est une « taille de jeu de travail » vous mesurez?

Il est la partie de la mémoire allouée qui est conservé dans la mémoire vive.

Si vous avez une application qui alloue 1Go de mémoire, et vous avez seulement 512 Mo de RAM, il est la taille de jeu de travail sera 512Mo. Bien qu'il « utilise » 1Go de mémoire!

Lorsque vous exécutez une autre application qui a besoin de mémoire, OS libérera automatiquement un peu de RAM en déplaçant des blocs rarement utilisés de la « mémoire » sur le disque dur.

Votre allocation de mémoire virtuelle restera le même, mais d'autres pages sera sur le disque dur et moins dans la RAM. la taille du jeu de travail diminuera.

De là, vous devriez avoir compris ce point, qu'il est inutile d'essayer de minimiser la taille de travail. Tu ne rien obtenir. Vous êtes ne pas libérer de la mémoire dans tous les sens . Vous êtes juste déchargeant les données sur le disque dur.

Mais le système le fera automatiquement quand il a besoin. Et il n'y a pas de point faire de la place dans la mémoire vive jusqu'à ce qu'il soit nécessaire. Vous êtes juste ralentir votre application, voilà tout.

TLDR : "la taille du jeu de travail" n'est pas "comment utilise beaucoup d'applications de mémoire". Il est « combien est juste prêt maintenant ». Ne pas essayer de le minimiser, vous êtes juste faire empirer les choses.

Gestionnaire de mémoire Delphi

OS vous donne la mémoire virtuelle dans les pages de 4Ko. Mais souvent, vous en avez besoin en morceaux beaucoup plus petits. Par exemple, 4 octets pour votre entier, ou 32 octets pour une certaine structure. La solution?

gestionnaire de mémoire d'application, tels que FastMM ou BorlandMM ou autres.

Il est de l'emploi à allouer de la mémoire dans les pages du système d'exploitation, puis vous donner de petits morceaux de ces pages lorsque vous en avez besoin.

En d'autres termes, lorsque vous demandez 14 octets de mémoire, ce qui arrive:

  1. Vous demandez FastMM 14 octets de mémoire.
  2. FastMM demande pour OS 1 page de la mémoire (4096 octets).
  3. OS accorde une page de mémoire, sauvegardant avec RAM (il est stocké dans la RAM réelle).
  4. FastMM enregistre cette page, coupe 14 octets et donne à vous.

Lorsque vous demandez encore 14 octets, FastMM coupe juste 14 autres octets de la même page.

Qu'est-ce qui se passe lorsque vous relâchez la mémoire? La même chose en arrière:

  1. Vous libérer 14 octets à FastMM. Rien ne se passe.
  2. Vous libérer 14 autres octets. FastMM voit que la page de 4096 octets, il alloué est maintenant complètement utilisé.
  3. Par conséquent, il libère la page, revenir au système.

Il convient de noter que FastMM ne peuvent pas libérer seulement 14 octets au système. Il doit libérer de la mémoire dans les pages. Jusqu'à ce que la page entière est libre, FastMM ne peut pas faire une chose. Personne ne peut.

Alors, pourquoi est ma taille de jeu de travail si grand, même si je tout desserrée?

Tout d'abord, la taille de votre groupe de travail n'est pas ce que vous devriez mesurer. La consommation de la mémoire virtuelle est. Mais si vous avez de grostravail taille ensemble, votre consommation de mémoire virtuelle sera élevé aussi.

Quel est le problème? Vous devriez être en mesure de comprendre par ce point.

Le mot Let vous allouer 1kb, puis 3kb de la mémoire. Quelle quantité de mémoire virtuelle avez-vous alloué? 4kb, 1 page.

Maintenant, vous relâchez 3Kb. Quelle quantité de mémoire virtuelle utilisez-vous maintenant? 1kb? Non, il est encore une page. Vous ne pouvez pas allouer moins de 1 page du système. Vous utilisez encore 4096 octets de mémoire virtuelle.

Imaginez si vous faites cela 1000 fois. 1kb, 3kb, 1kb, 3kb, 1kb, 3kb et ainsi de suite. Vous allouez 1000 * = 4 mb 4kb comme ça, et puis vous relâchez toutes les parties 3kB. Quelle quantité de mémoire virtuelle utilisez-vous maintenant?

Encore 4 mb. Parce que vous avez alloué 1000 pages dans un premier temps. Sur chaque page que vous avez pris 1kb et 3kB morceaux. Même si vous relâchez 3kB morceaux, 1KB morceaux continueront à garder chaque page que vous avez alloué en mémoire. Et chaque page prend 4Ko de mémoire virtuelle.

Gestionnaire de mémoire ne peut pas par magie « bouger » tous vos morceaux de 1kb ensemble. Ceci est impossible, parce que leurs adresses virtuelles peuvent être référencés de quelque part dans le code. Ce n'est pas un trait de FastMM.

Mais pourquoi avec BorlandMM tout fonctionne mieux?

Coincidence. Peut-être qu'il se trouve que BorlandMM vous donne la mémoire d'une manière légèrement différente de celle FastMM fait. La prochaine chose que vous savez, vous changer quelque chose dans votre application et BorlandMM agit comme FastMM a fait. Il est impossible pour un gestionnaire de mémoire pour empêcher complètement cet effet, appelé la fragmentation de la mémoire.

Alors, que dois-je faire?

Réponse courte est, pas beaucoup jusqu'à ce que vous dérange.

Vous voyez, avec les systèmes d'exploitation modernes, vous n'êtes pas vraiment manger la RAM de tout le monde. Par-dessus, OS échangera automatiquement vos pages quand il a besoin de RAM pour d'autres applications. Cela ne devrait pas être une préoccupation.

Et la mémoire « excessive » ne soit pas perdu. Bien que les pages sont allouées, 3kb de chacun est marqué comme « libre ». La prochaine fois que votre application a besoin de mémoire, gestionnaire de mémoire utilisera cet espace.

Mais si vous voulez vraiment aider, vous devez réorganiser vos allocations afin que ceux que vous avez l'intention de tenue sont faites d'abord, et ceux que vous allez bientôt libérer sont tous attribués après.

Comme ceci: 1kb, 1kb, 1kb, ..., 3kb, 3kb, 3kb ...

Si vous relâchez maintenant tous les morceaux de 3kB, votre consommation de mémoire virtuelle baissera de manière significative.

Ce n'est pas toujours possible. S'il est impossible, alors ne rien faire. Il est plus ou moins bien comme il est.

Et P.S.

Vous ne devriez pas allouera 500 formes en premier lieu. Ceci est clairement pas un chemin à parcourir. Résoudre ce problème, et vous aurez même pas besoin de penser à l'allocation de mémoire et de libérer.

J'espère que cela efface les choses, parce que quatre postes sur le même sujet, franchement, est un peu trop.

Quelles sont les statistiques de heapmanager (GetHeapStatus) sur le point que 160MB est encore attribué?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top