Inconvénients d'utiliser /LARGEADDRESSAWARE pour les exécutables Windows 32 bits?
nous devons relier un de nos exécutables avec ce drapeau car il utilise beaucoup de mémoire.
Mais pourquoi accorder un traitement spécial à un EXE file. Pourquoi ne pas normaliser on / LARGEADDRESSAWARE?
donc la question Est: y a-t-il quelque chose de mal à utiliser /LARGEADDRESSAWARE même si vous n'en avez pas besoin? Pourquoi ne pas l'utiliser comme standard pour tous les fichiers EXE?
3 réponses
appliquer aveuglément le drapeau LargeAddressAware
à votre exécutable de 32 bits déploie une bombe à retardement !
en plaçant ce drapeau vous témoignent de L'OS:
oui, mon application (et tous les DLLs chargés pendant l'exécution) peut gérer des adresses mémoire jusqu'à 4 Go.
alors ne limitez pas le SAV pour le processus à 2 Go mais déverrouillez le gamme complète (de 4 Go)".
mais pouvez-vous vraiment garantir?
assumez-vous la responsabilité de tous les DLLs du système, des redistribuables microsoft et des modules tiers que votre processus peut utiliser?
habituellement, l'allocation de mémoire renvoie des adresses virtuelles de bas en haut. donc, à moins que votre processus consomme beaucoup de mémoire (ou qu'il ait un espace d'adresse virtuel très fragmenté), il n'utilisera jamais d'adresses au-delà de 2 GO de limite. cela cache les bogues liés aux adresses hautes.
si de tels bogues existent, ils sont difficiles à identifier. ils apparaîtront sporadiquement "tôt ou tard". c'est juste une question de temps.
heureusement, il ya un commutateur très pratique à l'échelle du système intégré dans le système d'exploitation windows:
pour les tests, utilisez le paramètre MEM_TOP_DOWN registry.
cela force tous les allocations de mémoire pour aller du haut vers le bas, au lieu de la base normale vers le haut.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"AllocationPreference"=dword:00100000
(ici hex 0x100000. nécessite redémarrage de windows, bien sûr)
avec ce commutateur activé, vous identifierez les problèmes" plus tôt "plutôt que"plus tard". idéalement, vous verrez "dès le début".
note latérale: pour la première analyse je recommande fortement l'outil VMmap
( SysInternals ).
conclusions:
lorsque vous appliquez le drapeau LAA à votre exécutable de 32 bits, il est obligatoire de le tester entièrement sur un système d'exploitation x64 avec le commutateur AllocationPreference
réglé au sommet.
pour les numéros dans votre propre code vous pouvez être en mesure de les corriger.
juste pour nommer un exemple très évident: utilisez des entiers non signés au lieu des entiers signés pour les pointeurs de mémoire.
lorsque vous rencontrez des problèmes avec les modules tiers vous devez demander à l'auteur de corriger ses bogues. à moins que cela ne soit fait, vous feriez mieux de supprimer le drapeau LargeAddressAware de votre exécutable.
une note sur les essais:
le commutateur de Registre MemTopDown n'atteint pas les résultats souhaités pour les tests unitaires qui sont exécutés par un "coureur d'essai" qui: elle-même est pas Laa permis.
voir: Essais unitaires pour la compatibilité x86 large Adresseware
PS:
le passage du code 32bit au Code 64bit est également très" lié " et très intéressant.
pour des exemples, voir:
- en tant que programmeur, de quoi ai-je besoin pour m'inquiéter quand passer aux fenêtres 64 bits?
- https://www.sec.cs.tu-bs.de/pubs/2016-ccs.pdf (deux fois les bits, deux fois la difficulté)
parce que beaucoup de code d'héritage est écrit avec l'attente que les pointeurs" négatifs " sont invalides. Tout ce qui se trouve dans les deux premiers Go d'un processus 32bit a le jeu msb.
en tant que tel, il est beaucoup plus facile pour Microsoft de le jouer en toute sécurité, et exigent des applications qui (a) ont besoin de la pleine 4Go et (b) ont été développés et testés dans un scénario de grande mémoire, pour simplement mettre le drapeau.
ce n'est pas - comme vous l'avez remarqué - que dur.
Raymond Chen - dans son blog The Old New Thing - couvre les questions de mise en marche pour toutes les applications (32bit).
Non, "legacy code" dans ce contexte (C/C++) n'est pas exclusivement de code qui joue laide des trucs avec le MSB de pointeurs.
il inclut également tout le code qui utilise 'int' pour stocker la différence entre deux pointeurs, ou la longueur d'une zone de mémoire, au lieu d'utiliser le type correct 'size_t' : 'int' étant signé a 31 bits, et ne peut pas gérer une valeur de plus de 2 Go.
Une façon de guérir une bonne partie de votre code est d'aller dessus et de le corriger tous de ces inoffensif "mélange signés et non signés" mises en garde. Il devrait faire une bonne partie du travail, au moins si vous n'avez pas défini la fonction où un argument de type int est en fait une longueur de mémoire.
cependant ce " legacy code "fonctionnera probablement apparemment pendant pas mal de temps, même si vous ne corrigez rien.
Vous n'aurez qu'à casser quand vous allez allouer plus de 2 Go un bloc. Ou quand vous comparerez deux pointeurs indépendants qui sont à plus de 2 Go l'un de l'autre.
Comme comparer des pointeurs non liés est techniquement un comportement non défini de toute façon, vous ne rencontrerez pas que beaucoup de code qui le fait (mais vous ne pouvez jamais être sûr).
Et très souvent, même si au total vous avez besoin de plus de 2 go, votre programme ne fait jamais des allocations simples qui sont plus grandes que cela. En fait dans les fenêtres, même avec LARGEADDRESSAWARE vous ne pourrez pas par défaut allouer autant étant donné la façon dont la mémoire est organisée. Vous auriez besoin de mélanger la DLL système autour d'obtenir un bloc continu de plus de 2 Go
mais les lois de Murphy dit que ce genre de code sera pauses un jour, il est juste que cela se produira très longtemps après que vous avez activé LARGEADRESSAWARE sans vérification, et quand personne ne se souviendra que cela a été fait.