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

jQuery Discussion :

Saturation mémoire avec DataTables


Sujet :

jQuery

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 50
    Points : 36
    Points
    36
    Par défaut Saturation mémoire avec DataTables
    Bonjour, j'ai des problèmes de fuites mémoires.

    J'affiche une table (avec le plugin DataTables) dans ma page HTML suivant une balise select (Select2) qui possède l'évenement change().
    Lorsque je sélectionne une valeur dans ma liste déroulante, j'ai remarqué, via le task manager, que l'utilisation de mémoire augmentait et après un certain nombre de sélection, j'arrive à saturation mémoire (avec IE).

    Mon code fonctionne bien, il m'affiche bien les données, le soucis vient de la gestion de la mémoire.

    Voici mon code Html, j'ai 2 tables, la deuxième (table_statistic_10_ligne) s'affiche lorsque je clique sur une ligne de mon premier tableau (table_statistic_10), il affiche les détails de cette ligne:

    Code html : 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
    <body>
     <select id="Select2" name="D1" style="margin-right :50px">
     </select>
     <script>
        $("#Select2").change(function () { selectStat10(Select2.options[Select2.selectedIndex].value) });
     </script>
     <table id="table_statistic_10" class="display">
        <caption class="caption">Detail van verkopen</caption>
        <thead>
        </thead>
        <tbody>
        </tbody>
     </table>
      <br />
      <br />
     <table id="table_statistic_10_ligne" class="display">
        <thead>
        </thead>
        <tbody>
        </tbody>
     </table>
     <script type="text/javascript">
        fillSlectTagStat10();
     </script>
    </body>

    Voici mon code javascript, dans success, je récupère les valeurs (extraites d'un web service en C #) et je les remplis dans la dataTables :

    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
    function getStatistic10(dstart, dend, nam) {
    var response;
    var allstat10 = [];
    if (typeof myTabLigne10 != 'undefined') {
        myTabLigne10.fnClearTable();
    }
        $.ajax({
            type: 'GET',
            url: 'http://localhost:52251/Service1.asmx/Statistic_10_Entete',
            data: { "start": JSON.stringify(dstart), "end": JSON.stringify(dend), "name": JSON.stringify(nam) },
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (msg) {
                response = msg.d;
                for (var i = 0; i < response.Items.length; i++) {
                    var j = 0;
                    allstat10[i] = [response.Items[i].Nom, response.Items[i].Date, response.Items[i].Piece, response.Items[i].Tiers, number_format(response.Items[i].AmoutHT, 2, ',', ' '), number_format(response.Items[i].AmountTTC, 2, ',', ' '), response.Items[i].Quantite];
                }
                if (typeof myTabEntete10 != 'undefined') {
                    myTabEntete10.fnClearTable();
                }
                fillDataTableEntete10(allstat10, dstart, dend);
     
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert("error loading statistic 10");
                alert("Status: " + textStatus + "\n" + "Error: " + errorThrown);
            }
        });
    }
    Voici le code qui remplit la dataTables :

    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
    function fillDataTableEntete10(data, dstart, dend) {
    if ($("#table_statistic_10").css("visibility") == "hidden")
        $("#table_statistic_10").css("visibility", "visible");
    myTabEntete10 = $('#table_statistic_10').dataTable({
        'aaData': data,
        'aoColumns': [
            { "sTitle": "Nom" },
            { "sTitle": "Date" },
            { "sTitle": "Piece" },
            { "sTitle": "Tiers" },
            { "sTitle": "AmoutHT" },
            { "sTitle": "AmountTTC" },
            { "sTitle": "Quantite" }
        ],
     
        "sPaginationType": "full_numbers",
        "iDisplayLength": 10,
        "bJQueryUI": true,
        "bDestroy": true,
        "bPaginate": true,
        "bLengthChange": false,
        "bFilter": true,
        "bSort": false,
        "bInfo": false,
        "bAutoWidth": false,
        "sDom": '<"top"f<"clear">>rt<"bottom"ilp<"clear">>'
    });
    Dans ma liste déroulante, j'ai une valeur qui, une fois sélectionnée, me retourne environ 20 000 lignes. C'est grâce à cette valeur que j'ai remarqué les fuites mémoires.

    Je ne comprends pas, je pensais qu'il existait un Garbage Collector qui libérait automatiquement la mémoire.

    Comment puis-je remédier à cela? Je suis perdu...

    Merci.

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Bonjour

    Il y a un problème de conception, il faut construire la datatable directement à partir de la source de données.

    Exemple : https://datatables.net/release-datat...rces/ajax.html

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 50
    Points : 36
    Points
    36
    Par défaut
    Merci d'avoir répondu.

    Je récupère bien les données de mon web service dans un array javascript et ensuite je remplis la DataTables avec aaData et aoColumns.

    Je ne comprends pas bien l'usage de sAjaxsource.

    Je dois faire comment pour le chemin? Ça change quoi d'utiliser cela et non aaData?

  4. #4
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    De toute façon, vouloir afficher 20000 résultats (soit 140.000 cellules si on en croit ton code) est une aberration...
    D'une part, lequel de tes utilisateurs a besoin de toutes ces données en même temps ?
    D'autre part, un objet à 20.000 entrées est déjà relativement lourd à gérer pour JavaScript.
    Ensuite, imagine ce que tu demandes au navigateur : créer un tableau HTML contenant 140.000 cellules (la construction d'une table HTML est ce qu'il y a de plus lourd à gérer puisqu'il faut générer la structure puis analyser chaque élément afin de déterminer les dimensions à leur donner avant l'affichage), puis créer avec jQuery une référence sur chacune des lignes et chacune des cellules pour gérer l'apparence et les comportement. Sans compter qu'à chaque modification, il faut recalculer toutes les positions et toutes les dimensions.

    Bref, rien d'étonnant que ça rame...

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 50
    Points : 36
    Points
    36
    Par défaut
    Oui j'ai cité un cas parmi d'autre mais même si j'ai un tableau plus léger, à chaque nouvelle sélection dans ma liste déroulante, la mémoire va augmenter petit à petit.

    C'est de ce problème que je parle et comment empêcher cela?

  6. #6
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myTabEntete10 = $('#table_statistic_10').dataTable(...)
    Plutôt que de recréer un objet dataTable à chaque changement, tu pourrais te contenter de mettre à jour l'existant...

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 50
    Points : 36
    Points
    36
    Par défaut
    Merci pour l'idée mais j'ai été voir dans l'API pour voir s'il existait une méthode update (pour toute la table) mais apparemment non.
    Il y a juste celle-ci fnUpdate mais ce n'est ce que je recherche.

    Comment je pourrais mettre à jour autrement?

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 50
    Points : 36
    Points
    36
    Par défaut
    Résolu en utilisant fnClearTable() et fnAddData().

    Merci.

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 50
    Points : 36
    Points
    36
    Par défaut
    J'ai résolu le 1er soucis mais maintenant j'ai des fuites mémoires à cause de ce bout de code :

    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
    function getStatistic10(dstart, dend, nam) {
        var response;
        var allstat10 = [];
     
        if (typeof myTabLigne10 != 'undefined') {
            myTabLigne10.fnClearTable();
        }
     
            $.ajax({
                type: 'GET',
                url: 'http://localhost:52251/Service1.asmx/Statistic_10_Entete',
                data: { "start": JSON.stringify(dstart), "end": JSON.stringify(dend), "name": JSON.stringify(nam) },
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (msg) {
                    response = msg.d;
                    for (var i = 0; i < response.Items.length; i++) {
                        var j = 0;
                        allstat10[i] = [response.Items[i].Nom, response.Items[i].Date, response.Items[i].Piece, response.Items[i].Tiers, number_format(response.Items[i].AmoutHT, 2, ',', ' '), number_format(response.Items[i].AmountTTC, 2, ',', ' '), response.Items[i].Quantite];
                    }
                    //gestion de la mémoire
                    if (typeof myTabEntete10 != 'undefined') {
                        myTabEntete10.fnClearTable();//nettoie la 2e table si on clique sur display et que tableEntete est vide, car sinon tableLigne reste remplie
                        myTabEntete10.fnAddData(allstat10);
     
                    } else {
                        fillDataTableEntete10(allstat10, dstart, dend);
                    }
     
                    myTabEntete10.$('tr').click(function () {
                        var data = myTabEntete10.fnGetData(this);
                        $('tr').removeClass('row_selected');
                        $(this).addClass('row_selected');
                        loadData10(dstart, dend, data[2], data[3]);
                    }
     
                    );
     
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("error loading statistic 10");
                    alert("Status: " + textStatus + "\n" + "Error: " + errorThrown);
                }
            });
    }
    C'est la gestion du click qui provoque une fuite mémoire.

    Quand je retire ce bout de code, je n'ai pas de problèmes.

    Comment pourrais-je faire pour résoudre cela?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/03/2010, 12h16
  2. Réponses: 4
    Dernier message: 14/12/2008, 16h52
  3. Problème de mémoire avec BDE
    Par Machuet dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 10h11
  4. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20
  5. Comment bien gerer la mémoire avec les TStringList?
    Par david_chardonnet dans le forum Langage
    Réponses: 5
    Dernier message: 18/06/2003, 09h57

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