AJAX加载后Javascript清除内存中的对象

时间:2013-07-04 15:31:33

标签: javascript performance memory-leaks

我正在实施单页应用程序。

我有一个容器div(<div id="container"/>),我使用AJAX加载html内容。

// function that is overwritten by loadMenu functions
// and gets called before loading a new section 
function unbindPreviousSection() { };

// load contacts
function loadContactsMenu() {
    unbindPreviousSection();
    unbindPreviousSection = function () { };

    $.get("/Home/Contacts", function (data, status) {
        if (status === "success") {
            $("#content").html(data);
            contactsMenu.bind();
            unbindPreviousSection = contactsMenu.unbind;
        }
    });
};

// load profile
function loadProfileMenu() {
    unbindPreviousSection();
    unbindPreviousSection = function () { };

    $.get("/Home/Profile", function (data, status) {
        if (status === "success") {
            $("#content").html(data);
            unbindPreviousSection = function() {
                // specific unbind methods for this menu
            };
        }
    });
};

var contactsMenu = {};
(function () {
    var viewModel = null;

    contactsMenu.bind = function () {
        viewModel = {
            phones: ko.observableArray()
        };
    };

    contactsMenu.addPhone = function (phone) {
        viewModel.phones.push(phone);
    };

    contactsMenu.unbind = function () {
        viewModel = null;
    };
}());

在任何菜单加载功能中,我在内部调用上一个加载菜单的unbind方法。

loadContactsMenu();
loadProfileMenu();  // internally calls contactsMenu.unbind();

在加载任何数据之前,我调用unbindPreviousSection()函数来处理以前的菜单数据。

我的问题是:

viewModel对象中的contactsMenu变量在我调用contactsMenu.unbind()之后仍然存在,即使我将其设置为null? (它会造成内存泄漏吗?)

contactsMenu.addPhone函数是否会创建一个保存在内存viewModel变量中的闭包(因为在函数内部使用)?

1 个答案:

答案 0 :(得分:1)

  • 变量viewModel只是对象的引用。将viewModel设置为null后,它引用的对象将有资格进行垃圾回收(即变为不持久),除非您有对该对象的其他引用。
  • Closures仅在内存中保留对象,直到所有者函数运行。换句话说,Closure在开始时开始引用它的对象,并在结束时释放引用。关于addPhone函数,它实际上意味着它不会将viewModel的对象保留在内存中。

我建议使用Chrome Profiler检查此问题以及任何进一步的内存泄漏问题。您可以在那里获取内存快照,并查看将其保留在内存中的每个对象。