10
votes

Mémoire libre d'objets complexes en Java

J'essaie de faire de mon mieux pour expliquer ma question. Peut-être que c'est un peu abstrait.

J'ai lu une certaine littérature à ne pas appeler de GC explicitement dans le code Java, finalisez la méthode, pointant vers NULL, etc.

J'ai quelques gros fichiers XMLS (factures client). Utilisation de JAXB, les maréchaux de fichiers dans un objet Java complexe. Ses attributs sont des types de base (entier, BigDecimal, String, etc.), mais aussi une classe d'autres classes complexes, une liste d'autres classes, une liste de classes avec une liste d'attributs, etc.

Lorsque je fais mes affaires avec l'objet, je dois le supprimer de la mémoire. Certains XML sont très grands et je peux éviter une fuite de mémoire ou une situation supérieure.

Alors, mes questions sont:

  • est-ce suffisant pour attribuer un gros objet à NULL? Je lis cela, s'il y a des références douces, GC ne libérera pas l'objet.
  • devrais-je faire un dans la compensation de l'objet, de compenser toute la liste, affectant NULL aux attributs, etc.?
  • Qu'en est-il de Jaxb (j'utilise Java6, alors Jaxb est construit) et des références douces? Jaxb est plus rapide que le vieux Marshaller Jibx, mais je ne sais pas si c'est pire dans l'utilisation de la mémoire.
  • Dois-je envelopper la classe MegaComplex Jaxb avec une faiblence ou quelque chose comme ça?

    Excusez-moi pour mélanger des concepts d'utilisation de la mémoire Java, Jaxb, etc. J'étudie la stabilité d'un grand processus de course à pied et les fichiers .HProf des preuves que toutes les données clients de toutes les factures reste Mémoire. Excusez-moi si c'est une question simple, basique ou rare.

    Merci d'avance


1 commentaires

Le code peut-il avoir des références à des objets générés par JAXB après avoir été effectué avec le traitement JAXB lui-même? Pour combien de temps? De plus, je ne sais pas si cela est possible, mais pouvez-vous utiliser un constructeur afin de générer le résultat final sans avoir le besoin d'objets spécifiques à Jaxb lorsque vous avez terminé avec Marshalling?


3 Réponses :


9
votes

Sauf si quelque chose d'autre pointe des parties de votre gros objet (graphique), attribuez à la référence de la référence null suffit.

Soufest cependant, serait d'utiliser un profileur après l'exécution de votre application pendant un moment et de regarder les références de l'objet et de voir s'il y a quelque chose qui n'est pas correctement GC'ed.


1 commentaires

@haraldk, merci pour votre réponse. J'apprends aussi du profilage et de l'analyse de la mémoire. Je vais essayer de mettre un gros objet à NULL



3
votes

Vous avez écrit

hprof files evidence that all customers data of all invoices remains in memory. 


1 commentaires

Merci pour votre réponse. J'apprends aussi (démarrer) avec une analyse de la mémoire. Votre lien semble utile pour commencer avec le tapis (logiciel que j'ai recommandé d'analyser la mémoire, les fuites, etc.)



4
votes

est-il suffisant d'attribuer un gros objet à NULL? Je lis cela, s'il y a des références douces, GC ne libérera pas l'objet.

La réponse courte est oui . Il suffit d'assigner (toutes les fortes références à) un gros objet à NULL - si vous faites cela, l'objet ne sera plus considéré comme "fortement accessible" par le collecteur des ordures.

Les références douces ne seront pas un problème dans votre cas, car il est garanti que des objets accessibles doucement seront des ordures collectées avant qu'un OutofMemorororror est jeté. Ils pourraient bien empêcher le collecteur des ordures de collecter l'objet immédiatement (s'ils ne l'étaient pas, ils agiraient exactement les mêmes que des références faibles). Mais cette utilisation de la mémoire serait "temporaire", en ce sens qu'elle serait libérée s'il était nécessaire de remplir une demande d'allocation.

Dois-je faire une clairière en profondeur de l'objet, effacer toute la liste, affectant NULL aux attributs, etc.?

Ce serait probablement une mauvaise idée. Si les valeurs de champ ne sont référencées que par le gros objet externe, ils seront également recueillis lorsque le gros objet est collecté. Et s'ils ne le sont pas, les autres parties du code qui les renvoient ne seront pas heureuses de voir que vous supprimez des membres d'une liste qu'ils utilisent!

Dans le meilleur cas, cela ne fait rien et dans le pire des cas, cela brisera votre programme. Ne laissez pas le leurre de cela vous distraire de vous distraire de répondre à la seule question réelle de savoir si votre objet est fortement accessible ou non.

Qu'en est-il de Jaxb (j'utilise Java6, donc Jaxb est construit) et des références douces? Jaxb est plus rapide que le vieux marshaller Jibx, mais je ne sais pas si c'est pire dans l'utilisation de la mémoire.

Je ne connais pas particulièrement la performance relative et l'espace de ces bibliothèques. Mais en général, il est prudent d'assumer une attitude très forte "innocente jusqu'à preuve de culabilité prouvée" avec des bibliothèques principales. S'il y avait un bug de fuite de mémoire, cela aurait probablement été trouvé, rapporté et corrigé d'ici (sauf si vous faites quelque chose très niche).

S'il y a une fuite de mémoire, j'ai 59,9% sûr que ce soit votre propre code qui est en faute.

Dois-je envelopper la classe MegaComplex Jaxb avec une faiblence ou quelque chose comme ça?

Cela ressemble à vous lancer peut lancer des "correctifs" du GC au problème sans réfléchir à ce qui est réellement nécessaire.

Si la classe JAXB doit être faiblement référencée, alors tout cela signifie que c'est une bonne idée (et il devrait y être déjà). Mais si cela ne devrait pas, alors ne le fais pas. Un faible référencement est plus une question de la sémantique globale et ne devrait pas être quelque chose que vous introduisez spécifiquement pour éviter les problèmes de mémoire.

Si le code externe a besoin d'une référence à l'objet, il a besoin d'une référence - il n'y a pas de magie que vous pouvez faire pour que l'intude soit recueillie encore encore disponible. Si cela n'a pas besoin d'une référence (au-delà d'un certain point), il n'a pas besoin d'un du tout - mieux pour annuler une référence standard [forte], ou le laisser tomber hors de portée. Les références faibles sont une situation spécialisée et sont généralement utilisées lorsque vous n'avez pas de contrôle total sur le point où un objet cesse d'être pertinent. Qui est probablement pas le cas ici.

Les fichiers .HProf de la preuve que toutes les données des clients de toutes les factures restent en mémoire.

Cela suggère qu'ils sont effectivement référencés plus longtemps que nécessaire.

La bonne nouvelle est que le fichier HPROF contiendra des détails sur ce qui les référencent exactement. Regardez une instance de facturation que vous vous attendriez à avoir été flated et voyez ce qui lui fait référence et l'empêchent d'être grevée. Ensuite, regardez dans la classe en question pour voir comment vous vous attendez à ce que la référence soit libérée, et pourquoi cela n'a pas été dans ce cas.

Toutes les bonnes performances / la peau de peau de mémoire sont basées sur des mesures. Prendre des décharges de tas et inspecter les instances et les références, est vos mesures. Faites cela et agissez sur les résultats, plutôt que d'essayer d'envelopper des choses dans des faiblesses sur l'espoir que cela pourrait aider.


1 commentaires

Merci pour votre réponse bien expliquée et détaillée. Je commence par ce genre de problèmes (gestion de la mémoire), et je ne veux pas faire les choses "sur l'espoir qui pourrait aider". Ma question était aussi complexe que mon objet de facturation et je mélange des concepts. Je vais essayer vos conseils avec la méthode "Essai et Erreur", prenant des décharges de tas, le profilage et les analyser. Merci