IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Problème de StackOverflowException


Sujet :

VB.NET

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut Problème de StackOverflowException
    Bonjour,

    Je développe un Batch de traitement de grand volume de données, extraction de données d'un fichier csv puis l'intégration en base. Tout marche bien, mais au retour quand je liber la mémoire (.dispose ...etc) J'ai un retourne de StackOverflowException
    Un Bug dû au appel récursif des fonction système tel que dispose fait sauter le traitement ;-((

    Avez vous une idée pour résoudre le Bug???
    Merci par avance.

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 299
    Par défaut
    Sans code, personne ne pourra t'apporter de réponses à ton problème (sauf madame Irma ) !

    Tu dis que le stack overflow intervient en libérant de la mémoire ? C'est bizarre car il devrait survenir lorsqu'il y a un trop grand nombre d'appel à ta fonction récursive.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut Ci-après le code
    Effectivement, ci-après le code. En fait l'objet tmp_ficInter1 contient plus de 25000 éléments voir dès fois plus de 100000. la transation se fait très bien, mais quand il arrive au tmp_ficInter1.dispose() là sa saut systématiquement ;-((???!!!!!
    Merci,



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    Public Function Sychonise_fic_inter( ByRef tmp_ficInter1 As OfficeElevage.FcovFicInter ) As Int32
                Dim conn As Ofival.Designs.Connection.GenericConnection = Ofival.Designs.Connection.GenericConnection.Instance
    
    
                Dim t2 As IDbTransaction
                traitement.Connection = conn
                tmp_ficInter1.Connection = conn
               
                conn.Open()
                t = conn.BeginTransaction(False)
                Try
    
                   
                    t2 = conn.BeginTransaction(False)
                    traitement.launchIntegrationInterSigal(id_traitement)
                    t2.Commit()
                    Return id_traitement
                Catch ex As Exception
                    Try
                 
                        If Not IsNothing(t2) Then
                            t2.Rollback()
                        End If
    
                    Catch
                    End Try
                    ' Throw ex
                    Dim msg As String = String.Format("Erreur pendant {0} : {1}", "Erreur lors de Synchronisation des Interventions Sigal", ex.ToString)
                    Throw New Exception(msg, ex)
                Finally
                    If Not IsNothing(conn) Then
                        conn.Close()
                        conn.Dispose()
                        conn = Nothing
                        GC.Collect()
                    End If
                   
    
                    If Not IsNothing(tmp_ficInter1) Then
                        tmp_ficInter1.Dispose()
                        tmp_ficInter1 = Nothing
                        GC.Collect()
                    End If
                    
                End Try
    
            End Function

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    299
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 299
    Par défaut
    OK, merci.

    Tu as une balise code (le #) pour rendre ton code plus lisible (tout comme les indentations).

    Je ne vois rien de récursif dans ta méthode.

    Par contre, tu cherches à libérer le paramètre de ta fonction qui est en ByRef, c'est possiblement la source du problème (je ne vois pas l'intérêt de libérer ce paramètre dans ta fonction, peut être dans la méthode qui appelle cette fonction à la limite !)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
      If Not IsNothing(tmp_ficInter1) Then
                        tmp_ficInter1.Dispose()
                        tmp_ficInter1 = Nothing
                        GC.Collect()
                    End If
    l'intérêt est majeur, car mon programme est un traitemnt Batch qui fait le maping de données XML vers une BD relationnelle. donc j'ai besoin de mémoire.
    en fait, tmp_ficInter1 contient entre (25000 et 120000) enregistrements donc, quand tu fais un dispose il boucle sur toutes les occurrence de cet objet pour faire un release resources....
    Je vais essayé t as proposition faire le dispose la méthodes qui appelle la fonction...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut suite
    Même problème ;-(

  7. #7
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    moi je pense qu'on a pas suffisament de code pour comprendre le soucis

    l'erreur stackoverflow n'a rien à voir avec la mémoire prise par l'appli, ca veut dire que la pile des appels a débordé

    tu peux essayer en retirant tous les .dispose et les gc.collect, je pense que tu auras le meme soucis (et les variables seront bien disposées quand meme, le gc étant automatique, et les variables marquées comme destructibles à la sortie de la function (ou autre bloc))
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    merci, pour ta suggestion, j'essaie ça. Je te passerai le code (trop long) si ça ne marche pas...
    Merci, je te tien informé ça tourne

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    Bon, ça a l'air de marché mais pas pour longtemps. j'ai enlevé les disposes() et le traitement s'est bien passé pour la première partie.
    Vient la plus grande partie, c'est le Mapping de données XML To DB... j'ai eu un stackoverflow.. suite à une insertion en base... Effectivement c'est saturation de la pile des appel. Donc voici la suite de la première partie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     Protected Overrides Function InsertEntity(ByVal Entity As EntityBase) As Int32
                Dim e As FcovFicInter = CType(Entity, FcovFicInter)
     
                MyBase.InitCommand(Parameters.Proc_Create)
                With MyBase.EntityCommand
                    Try
                        .Parameters.Add(GetParameter(Parameters.Param_ReturnValue, DbType.Int32, 4, ParameterDirection.ReturnValue))
                        .Parameters.Add(GetParameter(Parameters.Field_t_id, DbType.Int32, 4, e.t_id))
                        .Parameters.Add(GetParameter(Parameters.Field_nume_inter, DbType.AnsiString, 15, e.nume_inter))
                        .Parameters.Add(GetParameter(Parameters.Field_num_ordre, DbType.AnsiString, 6, e.num_ordre))
                        .Parameters.Add(GetParameter(Parameters.Field_nbre_vala_bov, DbType.Int32, 4, e.nbre_vala_bov))
                        .Parameters.Add(GetParameter(Parameters.Field_nbre_vala_ovcap, DbType.Int32, 4, e.nbre_vala_ovcap))
                        .Parameters.Add(GetParameter(Parameters.Field_code_camp, DbType.AnsiString, 6, e.code_camp))
                        .Parameters.Add(GetParameter(Parameters.Field_nume_ede1, DbType.AnsiString, 14, e.nume_ede1))
                        .Parameters.Add(GetParameter(Parameters.Field_nume_ede2, DbType.AnsiString, 14, e.nume_ede2))
                        .Parameters.Add(GetParameter(Parameters.Field_nume_ede3, DbType.AnsiString, 14, e.nume_ede3))
                        .Parameters.Add(GetParameter(Parameters.Field_nume_ede4, DbType.AnsiString, 14, e.nume_ede4))
                        .Parameters.Add(GetParameter(Parameters.Field_nume_ede5, DbType.AnsiString, 14, e.nume_ede5))
     
                        .ExecuteNonQuery()
                        Return CInt(CType(.Parameters.Item(Parameters.Param_ReturnValue), IDbDataParameter).Value)
                    Finally
                        If Not MyBase.EntityCommand Is Nothing Then .Dispose()
                    End Try
                End With
            End Function
    cette fonction est appeler autant de fois qu'il y a de ligne cad 120000 et +
    -- cette premère partie marche après avoir supprimé les dispose.
    Voici un fragment de code de la 2ème et très long partie.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     Protected Overrides Function InsertEntity(ByVal Entity As EntityBase) As Int32
          MyBase.InitCommand("prs_tournee_ins") ' call, stored procedure
          With MyBase.EntityCommand
            .Parameters.Add(GetParameter("@RETURN_VALUE", DbType.Int32, 4, ParameterDirection.ReturnValue))
            .Parameters.Add(GetParameter("@tour_id", DbType.Decimal, 12, CType(Entity, tournee).tour_id))
            .Parameters.Add(GetParameter("@tour_num_ident", DbType.AnsiString, 30, CType(Entity, tournee).tour_num_ident))
          ...
            .ExecuteNonQuery()
            Return .Parameters.Item("@RETURN_VALUE").Value
            .Dispose()
          End With
        End Function
    Même chose une procedure S est appelée autant de fois qu'il y a de données, et la le problème de Stackoverf me rattrappe ;-(
    Merci pour vos suggestion ...
    Moi je pense à une autre solution qui est la séparation des 2 partie, je pense que VB.Net n'est pas fait pour ce genre de traitement MAPPING et ne supporte pas la montée en échelle.

  10. #10
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    moi je pense surtout que tu as mal codé !
    un stackoverflow vient toujours d'un problème d'analyse

    si a appelle b et que appelle a par exemple, tu auras forcément un stackoverflow

    si le but est de lire un fichier xml pour le mettre dans une bases de données, je vois pas en quoi tu aurais besoin d'appels de tas de fonction, en quelques lignes ca se fait bien ! (du code séquentiel, tu lis un objet, tu l'insert dans la base et tu passes au suivant)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    Effectivement, t'as raison, si a appelle b et b appelle a c'est mort, mais ce n'est pas le cas. Certainement il y a un problème d'analyse, mais je ne pourrai pas changer l'existant.. Le projet est fait par d'autres et moi je ne fais que des évolutions et optimisation du code pas de restructuration.

    Mais, c'est pas aussi simple que ça, le job ne fait pas que de lire et d'insérer. dans le code ci-dessus, il n'y a que la phase finale.

    Merci,
    Je te tiendrais informer de la suite...

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    enfin, j'ai trouvé la où ça bug exactement. quand je fais Objet.dispose()
    y un appel de la procédure ReleaseRessource() voir pièce jointe. Elle même appelle dispose()... Récursivité donc problème....

    La question, comment pourrai-je débloqué ça?
    Merci encore de votre aide précieuse

  13. #13
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    si c'est une classe à vous, il ne sert à rien de lui faire implémenter IDisposable déjà ! ca ne sert strictement à rien (sauf si vous gérez du COM ou autre objet unmanaged dedans, mais ca m'étonnerait)

    après si vous l'avez implémenté, vous l'avez mal fait, car la méthode dispose doit gérer un booléen IsDisposed (qui sert à éviter la réentrance ou le multiple dispose)

    fait voir le code la méthode dispose (ou supprime là ca sera plus simple !)

    et mettre des variables à nothing ne sert à rien à part faire des lignes de code !!!
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    Effectivement, je me suis étonné de voir ça aussi. Malheureusement je ne peux pas y toucher à cette méthode, vu qu'elle est utilisée par d'autres projets, C'est un objet Commun.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        Public Overridable Sub Dispose() Implements IDisposable.Dispose
          Me.ReleaseRessource()
    #If PERF Then
          EntityCounter.DisposeEntity(Me.GetType.FullName, "")
    #End If
          GC.SuppressFinalize(Me)
        End Sub
    Mais y a t-il un moyen de vider la pile des appels une fois un traitement en chaine est fini. Car dans la 2ème partie de mon traitement, je n'utilise pas trop d'appel récursif. ça me permettra d'exécuter la deuxième partie.

    Merci,

  15. #15
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    ca serait idiot de vider la pile et laisser le bug ... on est pas là pour donner des conseils dans le genre !!

    le mieux serait de dire à vos collègues qu'il faut modifier votre dll (et peut etre essayer de mieux comprendre le gc)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 26
    Par défaut
    A mon avis la solution est clair, c'est de supprimer la réimplementation de la méthode dispose()... vu que c'est déjà géré par VS, ça en ce qui concerne le projet sur lequel je bosse. Les autres j'en ai aucune idée.

Discussions similaires

  1. problème avec System.StackOverflowException
    Par Mario Rousson dans le forum VB.NET
    Réponses: 10
    Dernier message: 04/11/2011, 21h32
  2. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18
  3. Problème d'impression
    Par IngBen dans le forum C++Builder
    Réponses: 7
    Dernier message: 22/05/2002, 11h37
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10
  5. Réponses: 6
    Dernier message: 25/03/2002, 21h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo