Brissou de Mourièssou Créateur de sorts, depuis 1936.
Inscrit le: 30 Aoû 2007 Messages: 1510 Sujets: 26 Spécialité en worldedit: Développer des jeux vidéos pour le fun, donc world edit c'est comme faire une addition. Médailles: 2 (En savoir plus...)
Posté le: 19/09/07 18:03 Sujet du message: Poids en octet d'une location
J'ai effectué des tests afin de déterminer précisément le poids en octet d'une location en mémoire, une location non supprimée, donc du leak dans une map normale. Et malheureusement les résultats sont effrayants ...
Pour réaliser ce test j'ai utiliser ce simple déclencheur:
Gui:
Trigger:
Test Leak
Evénements
Joueur - Joueur 1 (Rouge) types a chat message containing l as Une sous-chaîne
Conditions
Actions
Custom script: local location loc = null Custom script: local real a = 0.0 Set aMax = (Real((Substring((Entered chat string), 2, (Length of (Entered chat string)))))) Custom script: loop Custom script: exitwhen a > udg_aMax Custom script: set loc = Location( 0, 0) Custom script: set a = a + 1.0 Custom script: endloop
Déroulement du test:
Tout d'abord j'attend quelque seconde après le lancement du jeu.
Je lance un message vide au travers du chat, car ça bouffe 300ko la première fois. Il ne fallait donc pas que ça soit pris en compte.
Ensuite il faut taper : lX, X étant le nombre de location devant être crée. (Maximum: 3800, au delà la boucle est automatiquement stoppé)
Résultat des tests: 1er test: (lancé à partir de l'éditeur)
1000 points : 316 ko -> 316 octets / point
2000 points : 680 ko -> 340 octets / point
3000 points : 1112 ko-> 370 octets / point
2nd test: (lancé à partir de la partie précédente -> Recommencer partie)
1000 points : 260 ko -> 260 octets / point
2000 points : 568 ko -> 284 octets / point
3000 points : 1156 ko-> 385 octets / point
3ème test: (lancé à partir de l'éditeur)
1000 points : 336 ko -> 336 octets / point
2000 points : 700 ko -> 350 octets / point
3000 points : 1020 ko-> 340 octets / point
Ce qui donne une moyenne de 331 octets.
Voilà c'était juste pour information, après on peut en déduire autre chose, il faudrait vérifier combien de location sont créées en moyenne pour une map et en déduire à partir de quand les fuites de mémoires deviennent nuisibles. _________________
Sachant que pour tout cela, il faut que tu prennent en compte les handles créées et accessoirement peut etre aussi les pointeurs vers ceux-ci.
Tu pourrais par exemple te passer de la variable loc et faire simplement un call Location(0,0) car tu leaks sur le pointeur local.
jmoritz a écrit:
Code:
Loop
set testloc = Location(10, 20)
call RemoveLocation(testloc)
set testloc = null
set testloc = Location(10, 20)
call RemoveLocation(testloc)
set testloc = null
set testloc = Location(10, 20)
call RemoveLocation(testloc)
set testloc = null
set testloc = Location(10, 20)
call RemoveLocation(testloc)
set testloc = null
endloop
Not only does this code look strange, the set testloc = null doesn't make any difference. First time you run this, it leaks 5 megs, but after that nothing.
Code:
function testlocals takes nothing returns nothing
local location testloc = Location(10, 20)
call RemoveLocation(testloc)
set testloc = null
endfunction
Loop
call testlocals()
endloop
In this case, set testloc = null makes a huge difference (like Peppar said). Memory usage is now the same as the first test: only an initial leak of around 5 MB. If you remove the set testloc = null, this will leak every time you run it. Strangely enough, the first run always leaks much more (10 times as much).
Most likely handles always get recycled, and the leak is caused by something else. My guess is a different kind of data structure is associated with local variables, in addition to the data associated with a handle. This data only gets destroyed when you set the local var to null.
In other words: the initial leak is not a leak, but simply memory reserved for future use.
Ce post explique, qu'avec tous les "anti-leak", la fonction leak quand meme environ 5Mo à la première utilisation, ce qui peut peut être expliquer certaines différences observées.
Citation:
Do be reminded that these leaks are small, and only affect performance if your map uses leaking functions a lot. And by that I mean 10,000 times or more. And even at 10,000 it only leaks a few megabytes...
Il faut garder en mémoire que ces leak sont petit, et n'affectent seulement les performance si votre carte utilise énormément de fonctions qui leak. Et par cela, je veux dire 10 000 fois ou plus. Et meme 10 000 fois ne "leakerait" que quelques mégaoctets. _________________
Bêta Systems:70% Bêta Spells:13% Bêta Arts & graphics:70%
Brissou de Mourièssou Créateur de sorts, depuis 1936.
Inscrit le: 30 Aoû 2007 Messages: 1510 Sujets: 26 Spécialité en worldedit: Développer des jeux vidéos pour le fun, donc world edit c'est comme faire une addition. Médailles: 2 (En savoir plus...)
Posté le: 19/09/07 21:35 Sujet du message:
Oui c'est bizarre qu'avec tout l'anti-leak qu'il y a ça leak complètement.
J'ai fait le calcul pour son test j'obtient le même résultat: 328 octets par location.
Il va falloir des tests plus poussées pour mieux comprendre le fonctionnement interne.
Je vais d'abord essayé sans la variable locale. Et ensuite passer à un nombre beaucoup plus important de location sur du long termes. _________________
Pour comprendre le leak il faut comprendre ceci :
Les variables locales sont des pointeurs, qui pointent vers un endroit de la mémoire qui stocke les handles (on l'appelera "handle array", bien qu'il ne soit pas prouvé que ce soit un array), chaque handle pointe vers un autre endroit de la mémoire (surement les "objets" eux memes).
Le premier scénario de leak, est l'objet en lui même qui n'est pas supprimé.
Le second, est celui qui fait que l'endroit ou est listé la handle (dans le handle array) n'est pas supprimé, même si l'objet l'es, lui ; entrainant alors aussi un leak (mais de moindre importance que le leak d'objet en lui même).
Pour simplifier le deuxième cas : lorsque tu pointes une variable sur une handle, cela incrémente un petit compteur sur la handle, qui compte le nombre de références vers celle-ci.
Le problème est que lorsqu'une variable locale est supprimée à la fin de l'execution d'une fonction, le compteur n'est pas mis à jour, la handle restera donc avec un compteur non nul, l'empèchant d'etre réutilisée pour le prochain objet créé. Il y donc un leak.
La solution à cela est donc de nullifier la variable à la fin de la fonction, ou tout du moins de changer sa valeur, car dans ces cas là, le compteur est correctement mis à jour.
Un petit problème survient alors pour les fonction qui renvoient une valeur : il nous est impossible de nullifier la variable.
Utiliser une variable globale, règle le problème. Exemple :
Jass:
function Fonction_qui_leak takes nothing returns location
local location loc = Location( 10, 10 )
return loc
endfunction
function Fonction_qui_ne_leak_pas takes nothing returns location
set udg_LOC = Location( 10, 10 )
return udg_LOC
endfunction
Il est bien évident que dans cette fonction là, on peut se passer de variable mais c'est pour l'exemple.
Une autre solution consiste à utiliser les variables "arguments" de la fonction, car celles-ci n'incrémentent pas les compteurs des handles.
Jass:
function ReplaceLocation takes location loc returns location
call RemoveLocation( loc )
set loc = Location( 10, 10 )
return loc
endfunction
//cette fonction ne leak pas
_________________
Bêta Systems:70% Bêta Spells:13% Bêta Arts & graphics:70%
Brissou de Mourièssou Créateur de sorts, depuis 1936.
Inscrit le: 30 Aoû 2007 Messages: 1510 Sujets: 26 Spécialité en worldedit: Développer des jeux vidéos pour le fun, donc world edit c'est comme faire une addition. Médailles: 2 (En savoir plus...)
Posté le: 20/09/07 10:16 Sujet du message:
Ok merci c'est bon à savoir.
Pour le deuxième type de leak, je suis ton avis global sur les fuites de mémoires, je le trouve négligeable. Je pense qu'il est bon de nullifier les variables quand on peut le faire facilement, ça coûte pas grand chose, mais devoir utiliser des tecnhiques poussées en utilisant une variable globale etc... c'est beaucoup de boulot pour un gain de 1 fps au bout d'une heure de jeu. :/ _________________
Tu peux aussi utiliser la technique de la déclarations des variables dans la déclaration de fonction, en passant comme argument null. Quitte à utiliser une deuxieme fonction pour simplifier la première.
Jass:
function createLoc takes location loc returns location
set loc = Location(10,10)
call RemoveLocation( loc )
return loc
endfunction
Page 1 sur 1 La question posée dans ce topic a été résolue !
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum