Подтвердить что ты не робот

Chrome не освобождает память, сбор мусора не происходит должным образом (библиотека Mootools/MochaUI)

Фон. В настоящее время я работаю над сайтом интрасети, использующим библиотеку MochaUI (работая из демонстрации виртуального рабочего стола), Я использую Mootools 1.2.4 и MochaUI 0.9.7. Окна, открытые в моей реализации "виртуального рабочего стола", загружают их содержимое через iframes. Некоторые загруженные страницы довольно сложны с точки зрения css и сценариев, поэтому важно, чтобы объекты Window были надлежащим образом собраны в мусор, когда пользователь закрывает окно. Об этом, по-видимому, заботится библиотека (при использовании Firefox она выполняет справедливую работу).

Обновление Изначально опубликованный вопрос стал слишком длинным после последующих изменений/обновлений. Название больше не было точным, поэтому я тоже изменил это. Также см. Мой ответ ниже для частичного решения.

Вот основные моменты:

  • Chrome goofs выглядит так:

    • Chrome не освобождает память, выделенную для объектов окна MochaUI, когда они закрыты. Вместо этого использование памяти Chrome замерзает (буквально) на уровне, достигнутом после того, как окно завершит загрузку содержимого iframe, установив нижнюю границу использования памяти до обновления страницы.
    • Память, используемая процессом, продолжает увеличиваться с последующим открытием/закрытием окна. В конце концов, достигается некоторый тип кепки, и использование памяти перестает подниматься, как круто/начинает колебаться, а не резко подниматься.
    • Эта проблема наиболее очевидна, когда окна, о которых идет речь, загружают довольно здоровенный (по памяти) iframe-контент. Окно, которое я использую для всех целей тестирования, загружает страницу 580 кб (без кэша) в ее iframe.
  • Как ни странно, ожидаемая сборка мусора имеет место, когда

    • браузер сведен к минимуму
    • открывается другая вкладка в том же окне браузера
    • В инструментах разработчика записывается временная шкала памяти. (вариант комедии)
    • Означает ли это поведение любые возможные подходы к решению # 1?
4b9b3361

Ответ 1

Я не уверен, что это было протестировано в Windows, но если это так, помните, что всякий раз, когда вы сворачиваете окно в Windows, он перемещает все данные в файл подкачки. При открытии окна снова он не будет перемещать блоки памяти обратно, если программа не пытается получить к ним доступ, и, таким образом, всякий мусор остается в файле подкачки, но на самом деле не собирается.

Если вы его автоматизировали, это не только замедлит работу программы, но и не поможет в проблемах с памятью.

см. следующий URL-адрес для получения дополнительной информации

https://micksmix.wordpress.com/2010/01/08/why-does-task-manager-show-an-applications-memory-usage-drop-after-minimizing-it-to-the-the-taskbar/

Ответ 2

Обновление
Следующие изменения функции MochaUI closJobs - это большие улучшения по сравнению с тем, что я ранее размещал здесь. Основное изменение - теперь событие iframe onunload вручную вызывается путем изменения свойства src вместо того, чтобы быть запущенным, когда метод windowEl.destroy удаляет iframe из DOM. (получил идею здесь).

Если вы хотите использовать этот код, просто удалите существующую функцию closJobs и скопируйте этот код на свое место. Он должен работать как с 0.9.7, так и с 0.9.8 MochaUI, а также с Mootools 1.2.4 или 1.3.


closingJobs: function(windowEl){        
    windowEl.setStyle('visibility', 'hidden');
    var instances = MUI.Windows.instances;
    var instance_id = windowEl.id   
    var cleanup_delay = 50;

  /*
  Reset canvases with width/height = 0.
  This pretty reliably frees a few hundred Kb of
  memory in chrome.
  */        
    instances[instance_id].canvasControlsEl.width = 0;
    instances[instance_id].canvasControlsEl.height = 0; 
    instances[instance_id].canvasEl.width = 0;
    instances[instance_id].canvasEl.height = 0;         

    if(instances[instance_id].options.loadMethod == 'iframe')
    {
 /*
 The following line determines how long to delay the execution of
 the windowEl.destroy function. The line below gives 10 milliseconds 
 per DOM element in the iframe document.
 You could probably do just as well with a hard-coded value.
 */         
        cleanup_delay = instances[instance_id].iframeEl.contentDocument.getElementsByTagName("*").length * 10;              

 /*
 Set the Browser property in the iframe window to Internet Explorer.
 This causes Mootools to run its purge function, which iterates over
 all the iframe document DOM elements, removing events/attributes etc.
 Assuming you have mootools included in the iframe content.     
 */
        if(instances[instance_id].iframeEl.contentDocument.defaultView.MooTools)
        {           
            if(instances[instance_id].iframeEl.contentDocument.defaultView.MooTools.version.contains("1.3"))                
                instances[instance_id].iframeEl.contentDocument.defaultView.Browser.ie = true;
            else        
                instances[instance_id].iframeEl.contentDocument.defaultView.Browser.Engine.trident = true;
        }                   

        instances[instance_id].iframeEl.src = "javascript:false";
    }       

    MUI.cleanWindow.delay(cleanup_delay, null, windowEl);       
},  

cleanWindow: function(windowEl)
{                               
    var instances = MUI.Windows.instances;
    var instance_id = windowEl.id
    if (Browser.ie){
        windowEl.dispose();
    }
    else {
        windowEl.destroy();
    }       
    instances[instance_id].fireEvent('onCloseComplete');

 /*
 Changed - Only execute getWindowWithHighestZindex() and focusWindow() 
 functions if there will actually be open windows after the 
 current one closes.
 */
    if (instances[instance_id].options.type != 'notification' && instances.__count__ > 1){
        var newFocus = MUI.getWindowWithHighestZindex();
        MUI.focusWindow(newFocus);
    }       
    if (this.loadingWorkspace) this.windowUnload();
    if (MUI.Dock && $(MUI.options.dock) && instances[instance_id].options.type == 'window'){
        var currentButton = $(instances[instance_id].options.id + '_dockTab');
        if (currentButton != null){
            MUI.Dock.dockSortables.removeItems(currentButton).destroy();
            currentButton = null; //Is this necessary?
        }           
        MUI.Desktop.setDesktopSize();
    }

    //Changed - moved this to the end of the function.
    delete instances[instance_id];  
}