none
Saturation mémoire avec DataTables (plugin JQuery) lorsque je charge des tables suivant une liste déroulante avec l'évenement change() RRS feed

  • Question

  • 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:

    <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 :

    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 :

    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.

    mercredi 26 mars 2014 20:54

Réponses

  • Résolu en utilisant fnClearTable() et fnAddData().

    Au lieu de recréer à chaque fois
    un objet dataTable, je mets à jour l'existant.

    Merci.

    • Marqué comme réponse jaycee23 jeudi 27 mars 2014 10:38
    • Non marqué comme réponse jaycee23 jeudi 27 mars 2014 11:39
    • Marqué comme réponse jaycee23 jeudi 27 mars 2014 13:50
    jeudi 27 mars 2014 10:38
  • J'ai changé mon code de cette manière :

    myTabEntete10.$('tr').bind('click',function () {
     ...
    }

    J'ai utilisé un bind et j'ai ajouté un unbind avant mon fnClearTable().

    Est-ce une bonne manière?

    • Marqué comme réponse jaycee23 jeudi 27 mars 2014 14:32
    jeudi 27 mars 2014 13:50

Toutes les réponses

  • Bonjour

    Le Garbage Collector existe bien, mais dans ce cas je soupçonne qu'on a des fuites de mémoire.

    Ici vous avez des détails sur comment vous pouvez les détecter/corriger

    http://msdn.microsoft.com/fr-fr/library/dn255003(v=vs.85).aspx

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    jeudi 27 mars 2014 09:37
  • Résolu en utilisant fnClearTable() et fnAddData().

    Au lieu de recréer à chaque fois
    un objet dataTable, je mets à jour l'existant.

    Merci.

    • Marqué comme réponse jaycee23 jeudi 27 mars 2014 10:38
    • Non marqué comme réponse jaycee23 jeudi 27 mars 2014 11:39
    • Marqué comme réponse jaycee23 jeudi 27 mars 2014 13:50
    jeudi 27 mars 2014 10:38
  • J'ai résolu le 1er soucis mais maintenant j'ai des fuites mémoires à cause de ce bout de code : 

    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?

    jeudi 27 mars 2014 11:43
  • Essayez de éliminer une par une les lignes dans Click. A la fin, laissez une fonction vide.
    Comme ça on peut déterminer plus exact d'où vient le problem - si c'est la fonction même vide ou une autre commande. . 


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    jeudi 27 mars 2014 12:23
  • J'ai changé mon code de cette manière :

    myTabEntete10.$('tr').bind('click',function () {
     ...
    }

    J'ai utilisé un bind et j'ai ajouté un unbind avant mon fnClearTable().

    Est-ce une bonne manière?

    • Marqué comme réponse jaycee23 jeudi 27 mars 2014 14:32
    jeudi 27 mars 2014 13:50
  • Je dirais que c'est mieux mais divers versions d'explorateurs peuvent me contredire.  La mémoire consommée reste constante? 


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    jeudi 27 mars 2014 13:58
  • Sous Internet Explorer, lorsque je sélectionne ma valeur qui consomme le plus, j'arrive à +- 400MB et ma plus basse valeur à 50 MB.

    J'ai fais plusieurs sélections à la suite et j'obtiens toujours des valeurs dans ces environs là.

    J'imagine que c'est mieux vu qu'avant j'avais la RAM qui augmentait tout le temps.

    jeudi 27 mars 2014 14:11
  • Dans ce cas je dirais qu'on n'a pas des fuites de mémoire.
    Donc c'est OK.

    Bon codage!


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    jeudi 27 mars 2014 14:29
  • Merci !
    jeudi 27 mars 2014 14:31