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

WinDev Discussion :

Erreur allocation mémoire


Sujet :

WinDev

  1. #1
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut Erreur allocation mémoire
    Bonjour,

    en windev12 j'obtiens le message suivant :

    Erreur à la ligne 253 du traitement Procédure locale pi_parcours_nomenc_extrait_ets_non.
    Vous avez appelé la fonction TableAjouteLigne.
    Pas assez de mémoire pour effectuer l'opération
    (l'allocation de 1 octets a échoué).
    Le message complet est en fin de conversation.

    Je suis sur un traitement itératif gourmand qui en effet alimente un certain nombre de tables windev et sérialise dans un tableau d'objets un grand nombre d'objets.
    Cela m'amène à beaucoup consommer de mémoire et mon plantage intervient lorsqu'il me reste approximativement 10% de mémoire disponible.
    Peut-être est-ce la faute à pas de chance car j'ai une test, à chaque itération vérifie la mémoire restante et si on est en deça des 10% vide le tableau d'objets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    API("KERNEL32","GlobalMemoryStatus",&wf_MEMORYSTATUS:dwLength)
    		si arrondi(wf_MEMORYSTATUS:dwMemoryLoad,0)>90 ALORS
    			TableauSupprimeTout(OF_AR:wcp_TA_articles_deja)
    			wf_nb_requetes=0
    			wf_nb_pseudolu=0
    			Multitâche(1000)	//	pause 10 secondes
          DélaiAvantFermeture(1000)
          Info("Vidage mémoire ok")
    			DélaiAvantFermeture()
    		FIN
    Je vais descendre la valeur testée à 80 mais je recherche une solution plus pérenne car j'imagine que si un autre traitement gourmand se lance juste après mon test, je risque tout de même de planter ...

    D'avance, merci pour vos pistes.

    Ci-après le message complet.

    Erreur à la ligne 253 du traitement Procédure locale pi_parcours_nomenc_extrait_ets_non.
    Vous avez appelé la fonction TableAjouteLigne.
    Pas assez de mémoire pour effectuer l'opération
    (l'allocation de 1 octets a échoué).

    Informations techniques

    Projet : devxof

    Dump de l'erreur du module <WD120OBJ.DLL> <12.00Pyn>.

    - Appel WL :
    Traitement de <c2scm003.PROCEDURE.pi_parcours_nomenc_extrait_ets_non>, ligne <253>, thread <0>
    Fonction <TableAjouteLigne>, n° de syntaxe <0>

    - Niveau : erreur fatale (EL_FATAL)

    - Code erreur : 10027

    - Code erreur WD55 : 0

    - Pas de code d'erreur système

    - Pas de message d'erreur système

    - Que s'est-il passé ?
    Pas assez de mémoire pour effectuer l'opération
    (l'allocation de 1 octets a échoué).

    - Infos de debug :
    Fonction (1,38)

    - Infos attachées :
    EIT_PILEWL :
    Procédure locale pi_parcours_nomenc_extrait_ets_non (c2scm003.PROCEDURE.pi_parcours_nomenc_extrait_ets_non), ligne 253
    Procédure locale pi_parcours_nomenc_extrait (c2scm003.PROCEDURE.pi_parcours_nomenc_extrait), ligne 6
    Procédure locale pi_parcours_nomenc (c2scm003.PROCEDURE.pi_parcours_nomenc), ligne 365
    Procédure locale pi_parcours_nomenc_lance (c2scm003.PROCEDURE.pi_parcours_nomenc_lance), ligne 34
    Procédure locale pi_validation_scm_v2 (c2scm003.PROCEDURE.pi_validation_scm_v2), ligne 135
    Procédure locale pi_Validation (c2scm003.PROCEDURE.pi_Validation), ligne 143
    Clic sur GTIGAF2 ( GTIBASYS ) (c2scm003.GTIBASYS.GTIGAF2), ligne 1
    Sélection du menu de _Menu.Fichier.Import_Ecritures_Paie_SAARI101 (c2SCM._Menu.Fichier.Import_Ecritures_Paie_SAARI101), ligne 1
    Initialisation de devxof (), ligne 155
    EIT_COMPOSANT :

    EIT_DATEHEURE : 27/09/2012 15:47:01

    - Identifiant dans le .err : 10027
    Cordialement,
    Christophe Charron

  2. #2
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Ma question peut paraître stupide mais pourquoi ne vides tu pas ton tableau "dès que tu peux" ou "le plus souvent possible" ?

    Si tu détectes une charge de 90 et que tu vides ton tableau pourquoi ne le vides tu pas avant ?
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  3. #3
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut
    Citation Envoyé par frenchsting Voir le message
    Ma question peut paraître stupide mais pourquoi ne vides tu pas ton tableau "dès que tu peux" ou "le plus souvent possible" ?

    Si tu détectes une charge de 90 et que tu vides ton tableau pourquoi ne le vides tu pas avant ?
    Parce que je stocke dans ce tableau le résultat de requêtes. Cela m'évite 90% de requêtes redondantes (des dizaines de milliers) qui sont hyper chronophages
    Cordialement,
    Christophe Charron

  4. #4
    Membre éclairé
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    615
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 615
    Points : 841
    Points
    841
    Par défaut
    Bonjour,
    tu n'as pas un moyen de récupérer les requêtes les plus fréquentes et ne stocker que celles-ci ou celles qui sont les plus gourmandes en temps.
    Quand tu vides ton tableau, c'est le récultat d'une requête ou de toutes les requêtes ? parce que dans le second cas, tu perds tout le bénéfice de ce que tu avais fait. Tu ne pourrais en vider qu'une partie...

    Bon dev
    Gancau

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    303
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 303
    Points : 812
    Points
    812
    Par défaut
    Salut !

    Citation Envoyé par Christophe Charron Voir le message
    Parce que je stocke dans ce tableau le résultat de requêtes. Cela m'évite 90% de requêtes redondantes (des dizaines de milliers) qui sont hyper chronophages
    Donc tu gères ton propre cache de données.

    Alors au moment de purger le tableau tu pourrais être sélectif, et choisir de supprimer les résultats les moins souvent sollicités, selon un critère au choix:
    • la fréquence d'accès,
    • la "fraîcheur" des données.


    Ainsi, tu peux ajouter pour chaque élément du tableau une information "score" ou "hit" qui comptabilise le nombre de fois qu'un élément du tableau est utilisé, et régulièrement tu supprimes les plus petits scores.

    Ou, tu peux ajouter pour chaque élément du tableau une "date de fraîcheur" qui est actualisée à chaque accès, et régulièrement tu supprimes les éléments dont la date de fraîcheur est la plus ancienne, ou est trop ancienne.

    Bref, te voilà dans l'obligation t'optimiser ton traitement et les possibilités sont nombreuses.

  6. #6
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut
    Citation Envoyé par gancau Voir le message
    Bonjour,
    tu n'as pas un moyen de récupérer les requêtes les plus fréquentes et ne stocker que celles-ci ou celles qui sont les plus gourmandes en temps.
    Quand tu vides ton tableau, c'est le récultat d'une requête ou de toutes les requêtes ? parce que dans le second cas, tu perds tout le bénéfice de ce que tu avais fait. Tu ne pourrais en vider qu'une partie...

    Bon dev
    Gancau
    Bien sûr, n'en vider qu'une partie mais laquelle. Il ne faut pas non plus que le temps gagné grâce à la mémorisation dans un tableau ne soit perdu par la gestion de ce tableau.
    Cordialement,
    Christophe Charron

  7. #7
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut
    Citation Envoyé par OnePoint Voir le message
    Salut !



    Donc tu gères ton propre cache de données.

    Alors au moment de purger le tableau tu pourrais être sélectif, et choisir de supprimer les résultats les moins souvent sollicités, selon un critère au choix:
    • la fréquence d'accès,
    • la "fraîcheur" des données.


    Ainsi, tu peux ajouter pour chaque élément du tableau une information "score" ou "hit" qui comptabilise le nombre de fois qu'un élément du tableau est utilisé, et régulièrement tu supprimes les plus petits scores.

    Ou, tu peux ajouter pour chaque élément du tableau une "date de fraîcheur" qui est actualisée à chaque accès, et régulièrement tu supprimes les éléments dont la date de fraîcheur est la plus ancienne, ou est trop ancienne.

    Bref, te voilà dans l'obligation t'optimiser ton traitement et les possibilités sont nombreuses.
    Même réponse qu'à l'interlocuteur précédent : si je perds le temps gagné par la mise en tableau par le vidage partiel, la mémorisation du nombre de l'âge du capitaine ou je ne sais quoi encore, autant ajouter la gestion en direct du brûlage de cierge auprès du saint patron des buggeurs professionnels. Au moins ce code pourra être recyclé pour d'autres informaticiens, dans d'autres applications.

    Bien sûr, j'ai descendu mon seuil de vidage à 80% d'occupation de la mémoire et je ne plante plus mais la méthode est aussi empirique que celle des cierges.

    Je pensais naïvement que Windows me dirait qu'il n'avait plus assez de mémoire une fois qu'il aurait épuisé le swap, voire qu'il n'aurait plus de place sur disque ... et pensais pouvoir agir en fonction de ces règles ...
    Cordialement,
    Christophe Charron

  8. #8
    Membre expert
    Avatar de mail.spam
    Homme Profil pro
    Développeur Windev et technicien maintenance
    Inscrit en
    Janvier 2008
    Messages
    1 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Windev et technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2008
    Messages : 1 914
    Points : 3 803
    Points
    3 803
    Par défaut
    Bonjour,

    Je ne sais pas trop si ce que je vais dire est correcte.

    Es-tu sur que lorsque tu utilise TableauSupprimeTout ta mémoire est bien libéré?
    Si ce n'est pas le cas regarde du coté de la fonction libérer ou VariableRAZ.
    la touche est ton amie. l'aide ne mord pas quand on la consulte...
    PS : n'oubliez jamais que nous ne sommes pas avec vous sur le projet. Donc plus vous donnez d'informations et d'exemples de codes et plus nous pourrons vous aider. (Un exemple vaut mieux que de longs discours...)

    Pensez à utiliser les votes et à cliquer sur , merci

  9. #9
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut
    Citation Envoyé par mail.spam Voir le message
    Bonjour,

    Je ne sais pas trop si ce que je vais dire est correcte.

    Es-tu sur que lorsque tu utilise TableauSupprimeTout ta mémoire est bien libéré?
    Si ce n'est pas le cas regarde du coté de la fonction libérer ou VariableRAZ.
    Oui, pas de souci de ce côté. D'une part, après la suppression je mets une tempo de 10 secondes pour laisser le temps à Windows/Windev de réaliser et d'autre part, je constate que ma mémoire dispo augmente considérablement.

    En fait ce que j'aimerai comprendre/savoir c'est pourquoi je me fais insulter pour 1 octet alors que je suis sensé encore disposer de, à la louche, 10% de mémoire ... Ce serait quand même un comble malchance que justement à ce moment je remplisse mon tableau à concurrence des 10% de mémoire restant ...
    Cordialement,
    Christophe Charron

  10. #10
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Je pense que l'insulte est due à windows, pas à windev. Ton programme demande 1 octet à windows qui lui refuse d'où plantage.

    Windows doit garder une réserve afin d'éviter les plantages du sytème par manque de mémoire. Peut-être y'a-t'il un paramétrage à mettre afin d'autoriser ton appli à taper dans cette réserve.
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  11. #11
    Membre émérite
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Points : 2 533
    Points
    2 533
    Par défaut
    Je ne sais pas de combien de mémoire ton poste dispose, mais il faut savoir que si tu développe en 32 bits, la mémoire libre d'un processus est limité à 2go (http://msdn.microsoft.com/fr-fr/libr...v=sql.90).aspx) quel que soit la quantité de mémoire disponible.

    D'autre part, dans une remarque tu dis :
    Je pensais naïvement que Windows me dirait qu'il n'avait plus assez de mémoire une fois qu'il aurait épuisé le swap, voire qu'il n'aurait plus de place sur disque ... et pensais pouvoir agir en fonction de ces règles ...
    Ce scénario serait pire au niveau vitesse globale du système, la gestion du swap est énormément chronophage et ralentirais la totalité du système sans parler des risques de plantages quand on atteint les limites de la mémoire dispo (mémoire vive + swap).

    Par contre, tu as peut être la solution de gérer ton cache de manière différente. Tu dis mettre en cache des requêtes qui sont très longues à exécuter. Pourquoi ne pas effectuer un cache sur disque (dans des fichiers textes par exemple) en ne gardant en mémoire que la référence au fichier concerné.

    Il est certain que ce mode de cache serait moins rapide que "tout en mémoire", mais il te permettrait de profiter d'une plus grande taille mémoire utilisable (l'espace libre sur le disque). Le fait d'écrire et de lire des données brute sur disque est globalement rapide, plus rapide, dans tous les cas, que d'exécuter certaines requêtes.

    Au mieux, tu peux gérer un cache à 2 niveaux, mémoire et disque.

    En dernier recours tu peux regarder ceci : http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx qui permets d'après ce que j'ai compris de dépasser la limite de 2go avec un processus 32 bits. Je ne l'ai jamais utiliser et personnellement ne m'aventurerais pas à l'utiliser en Windev.

    ------------------------

    Concernant
    Même réponse qu'à l'interlocuteur précédent : si je perds le temps gagné par la mise en tableau par le vidage partiel, la mémorisation du nombre de l'âge du capitaine ou je ne sais quoi encore, autant ajouter la gestion en direct du brûlage de cierge auprès du saint patron des buggeurs professionnels. Au moins ce code pourra être recyclé pour d'autres informaticiens, dans d'autres applications.
    Tout système de cache doit gérer la durée de vie des données en cache. quelque que soit la mémoire dont tu dispose, un jour ou l'autre elle risque d'être saturé. Le principal critère d'efficacité d'une mise en cache se fait d'ailleurs sur l'algorithme de recyclage des données. Voir ceci pour un début : http://fr.wikipedia.org/wiki/Algorit...ignes_de_cache
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  12. #12
    Membre confirmé Avatar de Christophe Charron
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    920
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 920
    Points : 606
    Points
    606
    Par défaut
    Pardon pour la réponse tardive et merci pour cet éclairage ...
    Viennent se greffer la-dessus le fait que ce soit une VM et quelques autres réglages exotiques ...
    Je vais baisser mon seuil de vidage et advienne que pourra !
    Cordialement,
    Christophe Charron

  13. #13
    Membre émérite
    Homme Profil pro
    Développeur et responsable micros/réseaux
    Inscrit en
    Octobre 2010
    Messages
    1 286
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur et responsable micros/réseaux
    Secteur : Bâtiment

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 286
    Points : 2 562
    Points
    2 562
    Par défaut
    Bonjour,

    je m'insère dans la discussion pour savoir si le traitement n'est pas trop chronophage car pas assez mis en étapes ...

    Si tu pouvais faire des tables intermédiaires contenant des données temporaires nécessaires à la suite, est-ce que tu ne pourrais pas gagner en mémoire et la laisser disponible pour le système et autres traitements ?

    Si le tableau est vidé régulièrement, c'est que les données qui y sont stockées ne sont plus nécessaires et que donc le traitement est pour moi séquensable : alimentation complète d'une table de base de données, traitement sur les données alimentées (en plusieurs étapes si nécessaire), purge totale de la table, ...

    J'ajoute également que le cache de données est en général effectué par le serveur de base de données qui stocke en mémoire les requêtes et les données correspondantes (cela fait partie de son rôle de serveur). Cependant, il faut que le serveur dispose de suffisamment de mémoire pour ne pas devoir nettoyer son cache régulièrement ...

    à bientôt,

    Nicolas

Discussions similaires

  1. Libérer mémoire si erreur allocation
    Par darkwall_37 dans le forum Débuter
    Réponses: 39
    Dernier message: 22/02/2013, 16h44
  2. Erreur d'allocation mémoire
    Par Sagee dans le forum Débuter
    Réponses: 5
    Dernier message: 18/04/2012, 12h03
  3. Erreur d'allocation mémoire - GTK+
    Par Jazzero dans le forum Débuter
    Réponses: 13
    Dernier message: 13/07/2009, 18h33
  4. Erreur Allocation mémoire
    Par Thordax dans le forum C++
    Réponses: 10
    Dernier message: 05/04/2006, 21h29
  5. Allocation mémoire dynamique
    Par ITISAR dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 21/01/2005, 09h59

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