調査 - jquery メモリリーク




IE6フレームとメモリリーク (2)

私がこの質問を始める前に、私はそれのあらゆる側面が間違っていることを理解しています。 それを覚えておいてください...

私は継承した2001年に開発された統合されたソフトフォンを持つCRM-ishイントラネットアプリケーションを持っています。 これは基本的に、アカウント管理のためのテレフォニーコントロールとWebベースのフロントエンドを統合するコレクションアプリケーションです。 (GenesysテレフォニーとAS400ベースの収集システム... MQSeriesを使用)

私はこれを「人生の終わり」と呼ぶ前に、このアプリケーションをできるだけ近代化しようとしています。 近代化しようとする私の試みの一環として、JS機能とUIのためにjQueryとjQuery UIを実装しました。 私はそれで狂っていませんが、それはかなりうんざりしています。

さて、問題を入力してください:私たちは現在IE6を使用しており、アプリケーションはフレームを使って構築されています。 jQueryライブラリの実装は、アプリケーションのふるいのような性質をメモリの観点から明らかにしました。 これは、起動時に現在約75Mbのメモリを消費しており、約2〜3時間後には150Mb〜300Mbのいずれかに成長します。 その後、ブラウザがクラッシュします。

私はメモリリークをフレーム間のクロストークに絞り込んだ。 私はsIEveとDripでページを個別にテストしましたが、リークは見つかりませんでした。 しかし、フレームセット内のページにアクセスして、それは時限の爆弾です。

答えは、フレームなしでアプリケーションを再設計し、より良いブラウザを使い始めることです。 それには2つの問題があります:

  1. 私はIE9でこれをテストしていますが、問題はまだありますが、もう少し管理されています

  2. 申請書の再設計には、約500,000ドルと6〜12ヶ月かかるでしょう。

誰もが "フレームリーク"の問題を解決する方法を知っていますか? 私はコード例を与えていないことを知っていますが、私は一般的な知識を探しています。 IEのCollectGarbage()メソッドをアプリケーションのすべてのページに対してonloadとonunloadで呼び出していますが、無駄です。 私はjQueryでempty()メソッドを呼び出そうとしました。 document.body要素のすべての子をnull設定しようとしました。 何も働いていません。

実際にはかなりのコスト削減機能が実装されているので、これらの変更をすべて取り消す必要はありません。

追加情報

私は、メモリリークが発生するシナリオを特定することができました。 私はそれがフレーム間の "クロストーク"だと思ったが、1つのフレームがリフレッシュされるときにメモリリークが発生するようだ。

私は同じページの5つのインスタンスを持つ基本的なフレームセットを設定しました(1つのセッションではほとんど漏れがありません)。

<html>
    <head>
        <title>Frame Leak Test</title>
    </head>
    <frameset cols="*" rows="50%,50%" frameborder="1">
        <frameset cols="33%,33%,34%" rows="100%">
            <frame src="http://npasappgeneqa02/live/" />
            <frame src="http://npasappgeneqa02/live/" />
            <frame src="http://npasappgeneqa02/live/" />
        </frameset>
        <frameset cols="50%,50%" rows="100%">
            <frame src="http://npasappgeneqa02/live/" />
            <frame src="http://npasappgeneqa02/live/" />
        </frameset>
    </frameset>
</html>

ロードされているインデックスページには、sIEveにリークはありません。

sIEveでフレームセットページをロードして自動リフレッシュをクリックすると、メモリリークは報告されません。 しかし、個々のフレームで右クリック→リフレッシュを実行すると、DOM内のロードされたアイテムの75%がリークとしてリストされます。

明らかに、オートリフレッシュはF5 /シフト+ F5リフレッシュに相当します。 そしてそれはページのメモリを消去します。 しかし、個々のフレームがリロードされると、メモリは決してクリアされません...明らかに。 ユーザーが見なければならないすべての画面がメインフレームにリロードされます。

フレームセット内にソフトフォンが存在するため、単にフレームセットをリフレッシュすることはできません。これは、フレームセットがリフレッシュされたり不適切にログアウトされた場合に、アマゴンドンをもたらすソフトフォンが存在するためです。

誰もそれをリフレッシュせずにフレームセットメモリを制御する方法を知っていますか?


JSLintまたはJSHintいずれかをJSLintてJSコードを実行することをお勧めします。

これらの2つのユーティリティ(*)はJavascriptのコード品質チェッカーです。 彼らが文句を言うのは、JSコードが有効な場所ですが、プログラミングの慣習が貧弱です。

彼らがあなたの問題を引き起こしていることの少なくともいくつかを拾い上げる可能性があります。

(* JSHintはJSLintのフォークですが、両方を試す価値があるので、十分に異なっています)


この特定の状況について最新情報を提供したかっただけです。 私はこのメモリリークの問題に対して許容可能な解決策を見つけたと思います。

  1. UI要素が必要なページで完全なjQueryUIライブラリを使用する代わりに、個別の最小化されたスクリプト(uicore + datepickerなど)を使用しました。
  2. 可能な限り、ウィジェットスクリプトを活用したUI要素は避けました。これが、最大の問題点が発生した場所です。
    • a。 これにより、 button要素とaccordion要素用のカスタムスクリプトを記述する必要がありました。
  3. このアプリケーションはframesetで実行されるため、 windowメソッド(つまり、 window.onloadwindow.onunload )を使用すると、ウィンドウ自体がframesetのみをロードまたはアンロードするため、機能しません。 これに対処するために、私はdocument.bodyメソッドを実装しました。具体的には、 document.body.onbeforeunloadを実行し、ハングアウトしていた参照をすべて削除するグローバルなアンバインドを行いました( $("*").unbind(); )。

上記の方法論では、IE6(およびIE8)での4時間のメモリ消費量が200〜250Mbから80〜95Mbに減少しました。 私の目標は、8時間消費を150Mb以下に抑えることでした。これは、この目標を達成すると思います。

すべてのお手伝いをしてくれてありがとう。





internet-explorer-6