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

Как я могу контролировать утечки памяти IE6 + jQuery + jQuery-ui?

Здесь образец страницы с паролем datepickers. Здесь результат капель для этого:

alt text http://www.picvault.info/images/537090308_omoya.png

Эта страница протекает неопределенно в IE6sp1, когда я нажимаю кнопку Refresh повторно (IE6sp3 +, Opera 9, Chrome2 и FF3 + кажутся хорошими). Память поднимается и никогда не опускается, пока я фактически не закрою браузер полностью.

Я также пробовал использовать последнюю новинку jquery (r6414) и последний стабильный пользовательский интерфейс (1.7.2), но это не имело никакого значения. Я пробовал разные вещи без успеха (CollectGarbage, AntiLeak, другие).

Я ищу решение, отличное от "использования другого браузера!! 1", так как я не контролирую это. Любая помощь будет принята с благодарностью!

Обновление 1: Я добавил это событие кнопки в цикл, и это то, что происходит (внезапное падение происходит, когда я завершаю IE): alt text

Обновление 2: Я подал сообщение об ошибке (скрещенные пальцы).

Обновление 3: Это также в список рассылки.

Обновление 4: Это (как указано в списке рассылки) не работает, и на самом деле все ухудшается:

$(window).bind("unload", function() {
  $('.hasDatepicker').datepicker('destroy');
  $(window).unbind();
}); 

Недостаточно просто называть destroy. Я все еще застрял в этом, и я очень близок к тому, чтобы вырвать jquery из проекта. Я люблю его (я действительно делаю!), Но если он сломан, я не могу его использовать.

Обновление 5: Запуск бонуса, еще 550 баллов одному полезному человеку!

Обновление 6:. Еще некоторое тестирование показало, что эта утечка существует в IE6 и IE6sp1, но была исправлена ​​в IE6sp2+. Теперь о ответах, которые у меня есть до сих пор...

До сих пор все ответы были следующими:

  • Запретить пользователям IE6sp0/sp1 или игнорировать их
  • Отладить jquery и решить проблему самостоятельно
  • Я не могу воспроизвести проблему.

Я знаю, что нищие не могут быть выборами, но это просто не ответы на мои проблемы.

Я не могу отказаться от своих пользователей. Они составляют 25% от пользовательской базы. Это пользовательское приложение, написанное для клиента, предназначенное для работы с IE6. Это не вариант отказа от IE6sp0/sp1. Это не вариант, чтобы рассказать моим клиентам, чтобы справиться с этим. Он протекает так быстро, что через пять минут некоторые из более слабых машин непригодны.

Кроме того, хотя я хотел бы стать ниндзя JS, поэтому я могу выследить непонятные утечки памяти в коде jquery (если это ошибка MS, а не jquery), я тоже не вижу, что это происходит.

Наконец, несколько человек воспроизвели проблему здесь и в списке рассылки. Если вы не можете его воспроизвести, у вас может быть IE6SP2 +, или вы не можете достаточно освежать.

Очевидно, эта проблема очень важна для меня (отсюда 6 ревизий, щедрот и т.д.), поэтому я открыт для новых идей, но, пожалуйста, имейте в виду, что ни одно из этих трех предложений не будет работать для меня.

Спасибо всем за ваше внимание и понимание. Пожалуйста, следите за ними!

Обновление 7:. Баунти закончилась, и ответ Кита был автоматически принят SO. Мне жаль, что только половина очков была присуждена (так как я сам не выбрал ответ), но я все еще действительно застрял, поэтому думаю, что половина справедлива.

Я надеюсь, что команда jquery/jquery-ui может исправить эту проблему, но я боюсь, что мне придется записать это как "невозможно (на данный момент)" и перестать использовать некоторые или все jquery. Спасибо всем за вашу помощь и внимание. Если кто-то приходит с реальным решением моей проблемы, отправьте сообщение, и я выясню, как вам вознаградить.

4b9b3361

Ответ 1

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

Последствия не того, чтобы зафиксировать это, - это то, что пользователи IE6 заметят, что их машина становится все медленнее и медленнее и в конечном итоге либо полностью или, скорее всего, сбой IE6.

Так что?

Действительно - почему это ваша проблема?

Ваш определенно не будет единственным сайтом, который они посещают с этой утечкой, и они будут регулярно сталкиваться с сбоем IE6, независимо от того, что вы делаете, потому что это то, что он делает.

Маловероятно, чтобы кто-либо еще на IE6 мог даже указать ваше приложение как те, которые утечки.

Наконец, когда IE6 рушится, он сообщает IE6 как виновника - вы можете на законных основаниях отметить, что это ошибка в IE6, которую Microsoft исправила в новой версии.

Ваше дорогое время лучше потратить на улучшение приложения для пользователей, не попавших в адский ад - ваше приложение должно в основном работать для пользователей IE6, но такая проблема может отнять все ваше время и не исправить их проблему. IE6 по-прежнему будет неподдерживаемой, аварийной, защищенной дырой в браузере.

Я подозреваю, что разработчики jQuery придерживаются того же мнения. Также вам нужно сделать некоторые действительно уродливые вещи, чтобы обойти эту ошибку в IE6, включая хакерскую работу DOM, которая останавливает утечку, но на самом деле намного медленнее.


Обновление

Хорошо, это нелегкая проблема для исправления. MS описывает ошибку IE6 (и дает рекомендации по ее исправлению) здесь: http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx

В основном это не проблема с javascript или jQuery - актуальная проблема с DOM IE6 - когда HTML-элементы добавляются на страницу (по javascript, а не на странице при загрузке) IE не может мусор собирает их, если они не созданы очень определенным образом.

Это обратно к тому, как jQuery UI создает элементы (см. ошибку порядка размещения DOM в ссылке выше), и поэтому это не то, что либо jQuery devs, либо вы можете легко исправить.

Итак, как вы решаете проблему? Ну, вы можете использовать устаревший всплывающий календарь для IE6, или вы можете написать свой собственный.

Я бы порекомендовал первое, но если вы действительно хотите построить последнее, вам нужно следовать следующим основным правилам:

  • Всегда добавляйте элементы сверху вниз - например, если вы хотите построить таблицу, добавьте элемент <table> в страницу DOM, затем добавьте <tr>, затем <td> и так далее. Это назад, так как гораздо быстрее построить всю таблицу, а затем добавить ее в DOM - к сожалению, там, где IE6 теряет отслеживание.

  • Используйте только атрибуты CSS и HTML 3.2 - звучит глупо, но IE6 создает дополнительные объекты для хранения дополнительных атрибутов (или свойств "expando" ), а также утечки.

  • Своего рода связано с (2), но поскольку @gradbot упоминает, что IE6 имеет проблемы с сборкой мусора javascript-переменными - если они ссылаются на элемент DOM внутри события, выпущенного из этого элемента, вы можете получить проблемы. Это также усугубляется ссылками javascript на элементы DOM, которые обладают свойствами "expando".

Если у вас есть просмотр в Интернете, возможно, уже существует раскрывающийся календарь DHTML, который придерживается этих правил - он не будет таким красивым, быстрым или настраиваемым, как пользовательский интерфейс jQuery, но я уверен, я видел, как это делалось без утечки в IE6.

Я считаю, что лучше всего сохранить как можно больше статичности - например, вы можете загружать сетку календаря (номера недель и заголовки дневных столбцов) на страницу, а затем динамически загружать их в числа (и ничего больше). Создайте числа дня как ссылки, с javascript в href - не самая лучшая практика, как правило, но гораздо менее вероятная для утечки в IE6.

Ответ 2

Очевидно, что проблемы, о которых вы описали, проистекают из недостатков IE6, которые вы не можете подорвать с помощью исправления программного обеспечения (будь то обновление jQuery, ручной вызов CollectGarbage или какой-либо другой взлом JavaScript/DOM).

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

  • Я бы предположил, что ваши клиенты/пользователи используют IE6 SP0 из-за какого-то стандартного или нормативного положения компании или даже из-за того, что некоторые старые веб-приложения, которые они все еще используют, не поддерживают более новые браузеры. Если это не вариант обновления до IE7 (или, следовательно, IE8), вы можете связаться с ИТ-отделом своих клиентов и вежливо указать, что обновление IE6 с последними пакетами обновлений не только устранит проблему с приложением, в котором они находятся оплачивая, но также исправляя многие недостатки безопасности и производительности, которые, несомненно, существуют в IE6 SP0. По общему признанию, это может быть не удобная ситуация, но она может решить проблемы, с которыми вы сталкиваетесь, при этом позволяя им работать с браузером, который по какой-либо причине нуждается.

  • Если вы можете убедить ИТ-отдел своих клиентов в том, что IE6 устарел, они могут позволить вашим пользователям перейти на новый браузер. Не стоит говорить о том, что кто-то, кто работает в ИТ-отделе, будет более охотно заставлять сотрудников обновлять часть программного обеспечения, если они знают, что это либо а) пронизано недостатками и дырами в безопасности, либо б) приближается к концу поддержки (как IE6 SP0). IE6 SP0 на XP Pro SP2 поддерживается до 13 июля 2010 года, поэтому он все еще имеет некоторое время, но, указывая на то, что наряду с другими недостатками/ограничениями, которые вы могли бы найти, они могли бы подумать над обновлением раньше, чем позже.

  • Если вы не можете убедить кого-либо в обновлении своих браузеров либо в IE6 SPX, либо в IE7/8, то я не знаю, есть ли у вас выбор, но чтобы удалить нарушительный элемент управления со своей страницы и преследуйте другой вариант, пока пользовательский браузер не разрешит его. Разумеется, многие варианты управления выбора даты доступны в Интернете, которые бы соответствовали вашим потребностям. Это может быть не так просто, как версия jQuery, но на данный момент у вас нет других вариантов.

Надеюсь, вы найдете решение!

Ответ 3

Эта проблема либо в части jQuery только для IE6, либо в общей части jQuery, которая не имеет специфического кода IE6 (как отмечено в комментариях). В любом случае, это все еще ошибка в jQuery, которая требует адресации. о: пусто Вам придется либо выкапывать себя в jQuery или файл с ошибкой билет. Если вам удастся это исправить, не забудьте приложить diff к bugtracker, поэтому проект немного улучшится.;)

Если я получу некоторое свободное время, я постараюсь помочь вам в этом.

Изменить

Хорошо, поэтому проблема кажется непреодолимой.

Утечка, с которой вы сталкиваетесь, - это проблема только с IE 6 SP 0, утечка, вызванная IE-подходом к DOM. Неважно, какую структуру JS вы используете, она отказывается работать правильно.

Итак, ваши текущие параметры:

  • Попробуйте, чтобы ваши пользователи обновили IE 6 до более новой версии/пакета обновления,
  • Устранить (как в утечке) в IE (потерять клиентов) или
  • Умереть, пытаясь работать с IE.

Но это не обязательно означает, что вы не можете это решить. Как насчет того, чтобы просто пытаться пройти мимо вещи из-за шерсти?

Показывать все не IE 6 SP 0 пользователь jQuery datepicker, и только IE 6 SP 0 еще один более устойчивый (и, возможно, базовый) датапикер с IE условные комментарии. Таким образом, вы можете держать глазные сладости/функциональность в своем программном обеспечении и позволить пользователям IE 6 иметь те же основные функции.

Возможно, это не такой чистый вариант, но вы все равно сможете использовать то, что хотите, и IE6 все равно сможет работать без утечки.

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

Ответ 4

попробуйте удалить эти объекты после уничтожения объекта datepicker:

$.datepicker = null;
$.fn.datepicker = null;

Ответ 5

Проблема с IE 6 заключается в том, что у нее есть два сборщика мусора. Один для JavaScript и один для DOM. Например, если вы присоединяете функцию к событию DOM и затем удаляете элемент DOM, функция все еще будет существовать в памяти.

Просмотрите . Это немного язык в щеку, но это хорошая информация.

Они исправили эту проблему в IE 7. Я пробовал вашу страницу в IE8 в Windows 7, и я не вижу утечки памяти.

Ответ 6

Проблема здесь немного глубже, чем "просто" jquery. JQuery вместе со многими другими браузерами "утечки" круговых ссылок между объектами DOM и объектными прослушивателями. Скажем, у вас есть поле ввода, которое прикрепляет к нему слушателя, затем вы удаляете элемент из dom и не имеете никакой ссылки на слушателя в вашем коде. Теперь любой современный браузер ( >= ie7, ff, chrome, safari, opera) будет жить с этим, а мусор собирает его, в то время как IE6 будет думать, что, поскольку есть прослушиватель, прикрепленный к элементу dom, он не должен мусор собирать dom и самого слушателя.

Чтобы обойти это, некоторые люди используют очень сложные шаблоны проектирования, например, в код событий в Google Doctype. Чтобы исправить проблему для IE6, вам действительно нужно переписать часть jquery для работы с проблемой IE6 и/или переключиться на другую библиотеку и/или не присоединить прослушиватели событий в приложении к событиям DOM.

Ответ 7

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

ОБНОВЛЕНИЕ. Проведя немного времени на этом, я убежден, что это не имеет никакого отношения к самому дате.

Мои тесты показывают, что, просто перезагружая фиктивную страницу каждые 1 секунду, видит, что происходит утечка памяти. Если вы затем включите jquery на этой странице, утечки немного увеличатся (накладные расходы на разбор script). Если вы затем добавите jquery-ui в микс, то снова произойдет еще одно небольшое увеличение утечки памяти.

Чтобы доказать это, если вы не перезагружаете страницу и вместо нее есть кнопка, которая просто добавляет ввод, создает датупик на нем, а затем удаляет его, вы видите очень мало, если какие-либо утечки.

Ответ 8

Взгляните на этот фрагмент, который очищает узлы DOM. Вы можете найти это полезным. fooobar.com/questions/183695/...

Ответ 9

Лучший отладчик, доступный для IE6, - это Visual Studio. (Даже бесплатная версия будет работать.) Как Джени упоминает, если ваша проблема происходит только в IE6, вы захотите отлаживать IE6, обращая особое внимание на код, который только там работает.