7
votes

Delphi String Fuite

Je travaille avec Delphi Xe et je rédige une demande qui utilise Remobjects SDK pour communiquer (au cas où cela pourrait être pertinent). J'ai débogué FastMM sur, et parfois (pas toujours) lorsque je ferme cela donne un avertissement sur une seule "fuite de mémoire inattendue". "Une fuite de mémoire inattendue s'est produite. Les fuites de petits blocs inattendus sont: 117-124 octets: UnicodeString x 1". Très occasionnellement, je reçois X2 rapporté.

Maintenant, ma compréhension est que les chaînes sont comptées, et comme il n'y a pas d'autre objet impliqué pour causer la fuite, quelle pourrait être la situation qui pourrait causer que cela se produise? Dans Cette question Stackoverflow Les gens ne peuvent pas trouver un moyen de faire une fuite.

S'il n'y a pas de manière évidente, je téléchargerai la dernière source FastMM (il semble ne pas être incluse avec la source XE).

[Modifier une fois résolu] La solution pour trouver ceci consistait à installer FastMM Source et à activer FullDebUNode d'obtenir la trace de la pile.


4 commentaires

Je trouve AQTime encore plus utile pour trouver des fuites de mémoire que le mode de débogage complet rapide mm. C'est précisément à cause de la façon dont FastMM signalant de telles fuites (vous indique d'abord une fuite de chaîne, au lieu de l'objet contenant la mémoire de chaîne fuite) que je préfère AQTime.


@Warren pas FastMM vous indique également l'objet qui possédait la chaîne. C'était mon souvenir, mais ça fait si longtemps que j'ai eu une fuite de mémoire !!


@jachguer la question est le bit juste avant le point d'interrogation. @David, aucun autre article n'est mentionné. Lorsque je fuit une classe, je reçois le type de classe et les cordes qu'il contient aussi.


Faites-le comme je l'ai dit dans ma réponse et vous obtiendrez une trace de pile aussi. Je ne me souviens pas des paramètres mais je suis sûr que vous pouvez le faire sortir de la documentation de FastMM.


4 Réponses :


6
votes

Vous pouvez fuir des cordes en libérant des enregistrements sur le tas avec Freemem au lieu de disposer ou si vous écrasez un enregistrement à l'aide de System.Move ou Fillchar. Dans le premier cas, le code de finalisation n'est pas exécuté et dans la seconde si le champ String était rempli d'une nil, il pensera qu'il est déjà effacé.

Si vous souhaitez trouver l'emplacement de la fuite, téléchargez FastMM et activez Fulldebugmode. Il inclura une trace de pile de l'endroit où la fuite s'est produite.


4 commentaires

Je ne fais rien de fantaisie ici - aucun enregistrement et aucune gestion de la mémoire manuelle.


Un objet de classe qui n'est pas libéré, qui contient la chaîne? Une gamme dynamique de chaîne où vous n'avez pas défini de longueur (tableau, 0)?


@Warren: le premier montrerait aussi la classe comme une fuite. Les matrices dynamiques sont également dénombrées, la seconde n'aurait donc pas d'importance.


@ MJ2008: Je rappelle vaguement l'une des sorties Delphes (2006?) Fuite des chaînes dans les blocs de Var global si vous les utilisiez dans un bloc de finalisation. Cela aurait été 2007 ou plus tôt, et cela fait longtemps que je l'ai rencontré, alors si c'était 2007, il a dû être corrigé dans une mise à jour.



5
votes

Je vois habituellement des fuites de string quand elles sont contenues dans d'autres objets qui n'ont pas été détruits correctement. Par exemple, un objet qui n'a pas été libéré. Cependant, vous vous attendez à voir cet objet rapporté aussi.

Le moyen de résoudre ce problème est de télécharger et d'utiliser la version complète de FastMM et de la configurer pour signaler les traces de pile lorsqu'il détecte des fuites. Lorsque vous faites cela, vous obtiendrez une trace complète de la pile du code qui a affecté l'objet à fuite et à ce stade, il est généralement clair ce que le problème est.


0 commentaires

5
votes

La seule façon qui vient à l'esprit où vous pouvez fuir une chaîne sans le casser délibérément (comme l'incrémentation manuelle de la référence ou de faire une opération de pointeur en désordre) consiste à utiliser ThreadVar.

Comme le fichier d'aide indique,

variables dynamiques qui sont ordinairement géré par le compilateur (longues chaînes, Cordes larges, matrices dynamiques, Les variantes et les interfaces) peuvent être déclaré avec filvar, mais le compilateur ne se libère pas automatiquement la mémoire allouée en tas créée par chaque fil d'exécution. Si tu utilises Ces types de données dans les variables de fil, Il est de votre responsabilité de disposer de leur mémoire de l'intérieur du Fil, avant que le fil se termine.

à côté de cela, il n'y a rien qui me vient à l'esprit qui n'était pas déjà déclaré.

[modifier par interrogateur] C'était bien le problème et le code spécifique était comme suit: < / p> xxx


0 commentaires

8
votes

Lorsque vous utilisez des constantes dactylographiées et en fonction de la commande de finalisation, elle était possible pour FastMM de signaler une fuite quand il n'y en a pas.

Fastmm: la mémoire fuite déclarée là où je pense que cela ne devrait pas. < / p>

En bref, lorsque l'unité FinaliséeFirst Obtenez la finalisation de la constante de SSTRing obtenez libérés. Après la finalisation de la unité est terminée, la finalisation de Finalisedlast obtenez-vous appelé. En elle est finalisation, il a appelé la méthode Femme de filet du FinalizedFirst méthode. La variable de Sstring obtient initialisé à nouveau et ne reçoit pas libéré comme finalisation de FinalizedFirst a déjà exécuté.

Unité finaledlast xxx

FinalizedFirst Unit xxx

fuites de projet xxx


0 commentaires