2017-03-13 1 views
1

J'analyse actuellement une exception OutOfMemoryException survenant dans notre application lors d'une sélection SQL.OutOfMemoryException avec SQL Select

Environnement:
- x86 .NET 4.6.1 application (Pas de possibilité de l'utiliser comme x64)
- Devart.Data 5.0.1491.0
- Devart.Data.Oracle 9.1.67.0
- Entity Framework 6.0.0.0
- Oracle 12c

Qu'est-ce qui se passe?
Une requête spécifique accédant à plusieurs tables contenant beaucoup de données renvoie cette exception. Cela ne se produit qu'après avoir utilisé l'application pendant un moment, d'abord cela fonctionne bien. Une fois que l'exception se produit, cette requête échoue toujours; d'autres travaillent cependant.

L'exception provient de:
Une exception de type 'System.OutOfMemoryException' a été générée. Stack Trace:

at Devart.Data.Oracle.OracleDataReader.a() 
at Devart.Data.Oracle.OracleDataReader.Read() 
[...] 

Quand vous faites:

context.Database.SqlQuery<T>(query, allParameters.ToArray()).ToList() 

contexte: est System.Data.Entity.DbContext
requête: Est-ce la requête SQL (chaîne) nous nous calculons
paramètres: contient 1 paramètre spécifiant le nombre maximum de résultats à retruner

Analyse:
Lors du profilage de l'application avec dotMemory, il n'y a pas de grande différence entre le moment où la requête fonctionne et le moment où elle ne fonctionne pas.
travail: total 507MB, 76MB utilisé par .NET
ne fonctionne pas: 535MB, 104MB utilisé par .NET
Nous sommes loin de la 2 Go disponible pour un processus .NET.

Lorsque vous effectuez la même requête avec le « Oracle SQL Developer » la requête réussit toujours ~ 30s

Lors de l'utilisation DBMonitor, nous pouvons voir un retard de ~ 25s entre la requête et la restauration (fait en raison d'une exception) . Les requêtes et les annulations ont toutes les deux Error 'Completed successfully'.

Est-ce que quelqu'un connaît une raison ou même une solution possible à ce problème? Est-ce que DevArt pourrait faussement jeter cette exception parce que, par ex. atteint un délai d'attente? Existe-t-il un cache interne détaché du processus .NET qui se remplit après un certain temps?

J'ai d'abord posté cette question sur les forums DevArt mais je n'ai pas obtenu de réponse.

Merci d'avance pour votre aide.

+0

Avez-vous vérifié la fragmentation du tas? https://www.jetbrains.com/help/dotmemory/2016.3/Heap_Fragmentation.html – Chris

Répondre

1

Comme suggéré here comme première option, essayez de définir la propriété FetchSize de votre OracleCommand explicitement à une valeur raisonnable (comme 100).

j'avais trouvé ce poste avant, mais je ne l'ai pas été en mesure de régler le FetchSize (même après avoir étudié pendant 2 heures maintenant). Nous n'instancions pas nous-mêmes le OracleCommand; cela se fait lors de l'exécution de la requête .

Utilisez le connection string pour spécifier la valeur et commencer par une très faible un pour vérifier si c'est la cause.

+0

J'avais déjà trouvé ce post mais je n'ai pas été en mesure de définir le FetchSize (même après avoir enquêté pendant 2h maintenant). Nous n'instancions pas le'OracleCommand 'nous-mêmes; cela se fait lors de l'exécution de la requête. Je m'attendais à trouver la propriété par défaut ici https://www.devart.com/dotconnect/oracle/docs/EFProviderConfiguration.html mais n'a pas. Savez-vous comment le configurer? – Philippe

+0

Vous ne pouvez pas le spécifier dans la [chaîne de connexion] (https://www.connectionstrings.com/oracle-provider-for-ole-db-oraoledb/controling-the-fetchsize/)? –

+0

Vous avez raison avec la chaîne de connexion, merci beaucoup! Les premiers tests montrent que l'augmentation de la valeur à 1000 résout le problème (je n'ai pas pu le reproduire pour l'instant); le diminuer à 50 jette toujours l'exception (la valeur par défaut est 100). Je dois maintenant étudier davantage pour comprendre l'impact (à première vue cela n'a pas de sens pour moi pourquoi augmenter la taille d'extraction réduit la mémoire utilisée) et le profil pour voir comment les temps d'exécution sont impactés. – Philippe