大家好!我正在开发某种事件日历,我正在使用jQuery作为前端,使用PHP作为后端。我有用PHP创建的所有日历数据并发送到客户端,JSON编码。
考虑以下代码(简化):
jQuery(document).ready(function($) {
// property which contains calendar object
this.Calendar;
// get calendar object
show_month();
/* Assign a click event to the next month button */
$('#cal_month .next span').live('click', function() {
var month = $(this).attr('id');
var year = $(this).attr('class');
show_month(month, year);
});
function show_month(month, year) {
// delete pointers to the current month object
window.Calendar = undefined;
// get new month object
window.Calendar = get_month(month, year);
/* doing some stuff with this object here, like output to the
document etc., no event bindings */
}
function get_month(month, year) {
var calendar;
$.ajax({
type: 'GET',
dataType: 'json',
async: false,
timeout: 100,
url: '../some_url.php?month='+month+'&year='+year,
success: function(result) { calendar = result; }
});
return calendar;
}
var counter = 0;
while (counter != 1000) {
$('#cal_month .next span').trigger('click');
counter ++;
}
});
手动切换月份以及制作循环会导致巨大的内存泄漏。我在这里和一般在互联网上阅读了一堆关于内存泄漏,js关闭等的信息,但我想我仍然有一些误解。我很高兴得到一些关于我的代码中出错的想法。
更新
我正在测量任务管理器中观看firefox.exe(其他浏览器遇到同样问题)的内存使用情况。即使我从页面导航,记忆也不会自由。经过一段时间后,它会导致性能下降,因为我可以使用600+ Mb。
我也编写了一个循环来切换月份(上面添加了代码)。
更新2
我使用全局的原因是在我的事件日历中我还有周视图和日视图,所以我希望一个活动的月份对象可用于处理这两个视图的函数,并且只销毁它并获得新的一个用户切换月份。我的问题恰好是全局变量的用法。那个解决了,现在试图找出如何保持对象可用,直到用户明确切换月份...
BTW,我创建了一个仅用于基准测试目的的while循环,它与我的实际代码无关。
答案 0 :(得分:4)
我很想知道为什么你认为存在内存泄漏问题。还有两个我认为与记忆无关的大问题,但也许更重要。
第一个问题是同步服务器调用。您应该主要从不使用同步调用,因为在请求正在进行时锁定浏览器。 编辑:在该循环中执行此操作1000次将锁定浏览器最多1000 * 100毫秒,这将导致一些用户体验问题。
其次是全局Calendar对象。除了依赖混乱的全局状态之外,你还无法做同样页面上有2个日历的简单事情。
以下代码解决了这两个问题。
jQuery(document).ready(function($) {
$('#cal_month .next span').live('click', function() {
var month = $(this).attr('id');
var year = $(this).attr('class');
generate_calendar(month, year);
});
generate_calendar();
function calendar_fetch_complete(result) {
var calendar = result;
/* doing some stuff with this object here, like output to the
document etc.*/
}
function generate_calendar(_month, _year) {
var month = _month || (new Date().getMonth() + 1),
year = _year || (new Date().getYear() + 1900);
$.ajax({
type: 'GET',
dataType: 'json',
url: '../some_url.php?month='+month+'&year='+year,
success: calendar_fetch_complete
});
}
});
答案 1 :(得分:2)
我建议使用像http://www.dynatrace.com/en/这样的工具,他们有时会提供帮助。
从John Resig本人那里查看本文http://ejohn.org/blog/deep-tracing-of-internet-explorer/。
尝试遵循firebug技巧: 我建议你再试一次。简单的萤火虫技巧。当您不在UI控件上使用/鼠标操作时,只需单击firebug的分析按钮即可。看看有多少函数和调用正在发生,看看有什么东西是ODD并且需要很长时间。它很好的简单技巧,但帮助解决像这样的问题... :)
答案 2 :(得分:1)
var counter = 0;
while (counter != 1000) {
$('#cal_month .next span').trigger('click');
counter ++;
}
什么?根据此代码,您将触发多个span元素1000次,并为每个元素请求1000次同步JSON,这将重写单个全局变量。这不是记忆“泄漏”,它已经筋疲力尽。
我建议重构你的代码以包含异步请求并取出while循环。
答案 3 :(得分:0)
你说有内存泄漏,但你是如何确定的呢?
可能您只是在查看浏览器进程内存使用情况。无论浏览器对内存做什么都不一定与你在javascript中做的事情有关。可能是javascript引擎没有释放它认为会再次使用的内存空间 - 无论你当前是否正在使用它。
请找到合适的工具来分析这个和/或提供有关您认为存在内存泄漏的原因的更多信息。
答案 4 :(得分:0)
while(counter!= 1000){ $('#cal_month .next span')。触发器('click'); counter ++; }
这看起来像是在为某些东西分配1000个触发器 - 你不能处理来自父对象的任何点击吗?