Grand nombre de tables et consommation de mémoire Hibernate

Je travaille sur un grand projet ERP qui a un modèle de firebase database avec environ 2100 tables. Avec “seulement” 500 tables mappées avec Hibernate, les applications déployées sur le serveur Web nécessitent environ 3 Go de mémoire de travail.

Existe-t-il un moyen de réduire l’empreinte mémoire du métamodèle d’Hibernate lorsqu’on utilise autant de tables dans une unité de persistance? Ou devrais-je simplement abandonner les ORM et utiliser JDBC (ou même jOOQ )?

Actuellement, j’utilise Hibernate 4.1.8, Spring 3.1.3, JBoss AS 7.1 et travaille avec la firebase database MSSQL.

Modifier:

Sortie d’histogramme de mémoire JavaMelody – avec 2 000 tables de test générées dont la scope est légèrement inférieure à celle du modèle de firebase database d’origine (d’où «seulement» 1,3 Go de mémoire utilisée)

Edit 2:

Analyse de tas Java MAT:

  • Suspects de fuite
  • Top consommateurs

Je rencontre le même problème, et avec succès je réduis la consommation de mémoire de xGB à 30M, le buildSessionFactory passe de 2min à 7 secondes.

Une partie importante de la solution est affichée ici

postInstantiate buildSessionFactory firebase database énorme / mémoire énorme

Une session d’hibernation ouverte aura tendance à accumuler des objects au fur et à mesure de son utilisation. Ce n’est pas une fuite de mémoire; une session hibernate est conçue pour être utilisée une seule fois pour une requête et met en cache des objects persistants (c.-à-d. en direct dans la session), ainsi que des requêtes et autres données. Si vous appelez session.toSsortingng() , vous verrez une liste exhaustive d’objects qui vivent dans la session.

Si vous travaillez avec un très grand nombre d’objects, envisagez de les manipuler par lots. Vous pouvez appeler session.clear() après chaque lot pour expulser les données en cache et les objects persistants de la session et réduire l’encombrement de la mémoire de la session (parfois de façon considérable).

Après avoir appelé session.clear() , sachez que les objects chargés avant cet appel reviennent à l’état détaché et qu’ils ne sont plus actifs pour la session en cours.

Vous pouvez également utiliser l’ extraction différée pour optimiser la quantité de données que hibernate doit charger pour gérer une opération donnée. Vous pouvez en savoir plus à ce sujet dans la documentation d’Hibernate. Je recommanderais d’activer la fonctionnalité de journalisation SQL d’Hibernate et de vérifier si hibernate récupère des données dont il n’a pas besoin.

Vous pouvez également configurer hibernate pour collecter des statistiques pouvant vous aider:

 sessionFactory.getStatistics().setStatisticsEnabled(true); 

Je suggère de faire le profilage de l’application en production ou de la mise en scène en utilisant la mélodie java pour savoir où ou qui utilise la mémoire maximale et en fonction du résultat du profilage, vous devez décider des modifications à appliquer à l’application.

La mélodie Java est très facile à intégrer et à configurer. En production, vous pouvez l’activer ou la désactiver en mettant à jour simplement le fichier web.xml.

Quel est le but de votre object hibernate, hibernate ne convient que pour CURD (créer, mettre à jour, lire, supprimer), mais ne convient pas pour le calcul. pour tout usage de calcul (spécialement une table croisée), il est préférable d’utiliser la procédure de stockage et les ibatis ensemble.