2010-10-09 3 views
3

Je travaille sur un programme qui analyse les données d'un fichier et les stocke dans une base de données HSQLDB. Lorsque l'analyseur rencontre des données, il crée des entités qui sont mappées à la base de données en utilisant JPA/Hibernate. Mon problème est que pendant l'analyse, l'application utilise de plus en plus de mémoire. J'ai utilisé avec succès des tables mises en cache pour que, une fois l'analyse terminée, la mémoire soit entièrement libérée, mais pendant l'analyse, elle utilise beaucoup plus que ce que je suis à l'aise.JPA/HSQLDB est toujours en train de manger toute ma mémoire

J'ai essayé de résoudre ce problème en appelant les méthodes flush et clear sur mon EntityManager, mais cela n'a eu aucun effet. J'ai également essayé de m'assurer que l'entité avec des références à toutes les autres entités est gardée en mémoire.

Les objets les plus volumineux en mémoire semblent être hsqldb.Sessions. Se pourrait-il que HSQlDb met en cache des charges de données pour chaque transaction? Il semble excessif d'avoir besoin de 1 Go de RAM pour se retrouver avec un DB de 120 Mo sur le disque, n'est-ce pas?

S'il vous plaît aviser sur quoi je pourrais essayer ensuite.

+0

Essayez gestionnaire d'entités de rinçage manuelle tout en persistant des entités. Appeler EntityManager.flush() peut effacer les références inutiles dans la mémoire. Mais je ne sais pas si cela va résoudre votre problème. –

+0

@feridcelik - Je suis actuellement en train de tirer et puis de dégager :) – willcodejavaforfood

Répondre

2

Après deux jours de discussion autour de HSQLDB, j'ai suivi les conseils de deux amis et changé la base de données en H2. L'empreinte mémoire au cours d'une transaction est d'environ un tiers maintenant et elle est également 20% plus rapide.

vraiment m'a surpris

+0

Il semblerait que vous utilisiez HSQLDB 1.8.x. L'utilisation de la mémoire de transaction de HSQLDB 2.0.x avec des tables CACHED est beaucoup plus faible. – fredt

+0

@fredt - Merci pour cela. Il est trop tard pour revenir à HSQLDB, mais pour mon prochain projet, je vais recommencer :) – willcodejavaforfood

2

Effectuez un vidage de tas et utilisez Eclipse MAT pour analyser où la mémoire est utilisée. Avec JPA, les résultats sont souvent surprenants et sans regarder l'utilisation réelle de la mémoire, vous poignardez souvent dans l'obscurité.

+0

bonne sueggestion comme je n'ai aucune idée pourquoi cela se produit. Je pensais juste effacer l'EntityManager libérerait toute la mémoire. – willcodejavaforfood

+0

Cela a révélé que c'est HSQLDB qui se maintient dans la mémoire pour une raison quelconque. Cela signifie-t-il qu'il s'agit d'un problème de configuration de base de données, d'un problème de conception d'application ou d'un problème de conception transactionnelle? :) – willcodejavaforfood

+0

Quelles classes utilisent le plus de mémoire? –

0

Il pourrait être différentes causes. Je voudrais décrire les outils pour l'analyse des fuites de mémoire: 1) d'abord, trouver le process_id dans votre gestionnaire de tâches;

2) puis prendre une décharge de tas:

jmap -dump:live,format=b,file=<filename> <process_id> 

3) analyser ensuite: a) jhat util:

jhat <file> 

b) (i recommande) installer le plugin Memory Analyzer Eclipse de

http://download.eclipse.org/mat/1.3/update-site/ 

(Eclipse: help-> installer un nouveau logiciel -> ajouter un référentiel)

l'installer et aller à sa perspective. ouvrir et sélectionnez l'option pour trouver des fuites de mémoire.

En cas de HSQLDB: habituellement MemoryAnalizer montre que la mémoire utilisée dans

CompiledStatementManager.csidmap 

-Alors vous assurer que vous appelez toujours

statement.close() 
Questions connexes