9
votes

Oracle T4CPreparedStatement des fuites de mémoire?

Un petit fond sur la demande que je vais parler dans les prochaines lignes:

xyz est une application de gestion de données de masquage de données Eclipse RCP Application: vous lui donnez une colonne de table source et une colonne de table cible, elle appliquerait une trasformation (cryptage / shuffling / etc.) et copier la ligne données de la table source à la table ciblée. Maintenant, lorsque je masque n tables à la fois, n threads sont lancés par cette application.

Voici le problème:

J'ai rencontré un problème de production sur le premier lancement de ladite application ci-dessus. Malheureusement, je n'ai aucun journal pour arriver à la racine. Cependant, j'ai essayé d'exécuter cette application dans la région de test et de faire un test de stress.

Quand j'ai recueilli des fichiers .HProf et les a rencontrés par un analyseur (yourkit), j'ai remarqué que des objets d'oracle.jdbc.driver.t4cpreparaDstatement étaient de retenue. L'analyse me dit également que l'une de mes classes tient une référence à cet objet préparé et ainsi, n threads ont n des objets tels. T4CPreparationStatement semble avoir des matrices de caractères: Lastboundchars et Bindchars chacun de la taille Char [300000].

Alors, j'ai étudié un peu (Google!), obtenu OJDBC6.jar et essayé de décompiler T4CPreparationStatement. Je vois que la T4CPrepadStatement s'étend à OraclePreparaStatement, qui gère de manière dynamique la taille de la matrice de Lastboundchars et des bindars.

Alors, mes questions sont ici:

  1. Avez-vous déjà rencontré un problème comme Ceci?
  2. Connaissez-vous la signification de Lastboundchars / Bindchars?
  3. Je suis nouveau au profilage, alors vous pense que je ne le fais pas correctement? (JE a également couru les HPROFS à travers le tapis - et c'était le principal identifié question - donc je ne pense pas vraiment que je pourrait être faux?)

    J'ai trouvé quelque chose de similaire sur le Web ici: http://forums.oracle.com/forums/thread.jspa?messageid=2860681

    Appréciez vos suggestions / conseils.


2 commentaires

1. Oui. 2. Oui. 3. Non. Il existe un livre blanc sur le site Oracle expliquant les compromis d'ingénierie de ces champs. oracle.com/technology/tech/ Java / SQLJ_JDBC / PDF / ...


Je suis également entré dans le même problème. Avez-vous des solutions?


3 Réponses :


9
votes

Bien que possible, il semble peu probable que vous ayez trouvé une énorme fuite de mémoire en 11g. Je commencerais par obtenir le SQL réel des curseurs fuite et en regardant dans le code pour que ce SQL soit créé. Une cause très fréquente de curseurs de fuite que j'ai trouvés dans le passé est le code comme celui-ci:

try {
PreparedStatment stmt = null;
stmt = con.prepareStatement("SOME AWESOME SQL");
//lots of lines of code that masks the problem
stmt = con.prepareStatment("DIFFERENT SQL"); //You just leaked "SOME AWESOME SQL"!!!
//lots more code
} finally {
stmt.close() //looks like everything is ok, but only the second one actually got closed
}


1 commentaires

AFFE, merci, pour l'indice. Je vais numériser mon code pour cela et postera des mises à jour



18
votes

J'ai rencontré le même problème. Bien que la fuite d'affece puisse être le problème, ce n'était pas mon problème et j'ai trouvé une réponse différente après avoir creusé:

Le pilote Oracle JDBC conserve des tampons dans lesquels des données sont lues comme une optimisation des performances. La taille de la mémoire tampon est calculée en fonction de la taille maximale de la ligne possible (donc varchar (2000) allouerait quelque chose comme 2000 Char S), multiplié par la taille de la récupération JDBC. Cela permet au conducteur de lire des données directement dans le tampon plutôt que d'attribuer à la demande qui serait (apparemment) être plus lente.

Chaque instruction préparée au sein de chaque connexion maintient un tampon de ce type. Si vous utilisez un grand pool de raccordement avec la mise en cache de relevé (ou votre cache préparé des objets manuellement, ou de les fuir ...) Vous pouvez ensuite manger rapidement beaucoup d'espace de tas. 1,6 Go dans mon cas!

Ceci est tout expliqué par Oracle eux-mêmes dans un PDF ici

Mon expérience était basée sur le pilote 11.2.0.3.


0 commentaires

0
votes

Dans mon cas, j'ai trouvé Cette réponse très utile et ainsi, Le problème peut être corrigé en modifiant le paramètre datasource Taille de cache de déclaration à une valeur vraiment faible.

J'utilise Weblogic, donc dans mon cas, je l'ai modifié à partir de la valeur par défaut 10 à 1

 Entrez la description de l'image ici

La raison est parce que le datasource gère l'objet T4CPreptaStatement en mémoire, donc en le réduisant à une petite valeur, vous vous débarrassez du problème


0 commentaires