1

私たちは、javascript タイマーでサーバーのデータをポーリングする asp.net mvc 3 アプリケーションを開発しています。データが返されたら、jquery 1.7.1 とノックアウト 2.0 を使用して表示します。ビューは、テキストとアイコンを含むいくつかの通知 div を表示するウィジェットです。

タイマー間隔を 5 秒に短縮して大量の通知を返すと、問題が発生します。ランダムな時間が経過すると、クロムの「Aw Snap」ページが表示されます。タイマーを 3 分から 30 分まで動かします。私たちのアプリケーションは、24 時間年中無休でブラウザで開く必要があることに注意してください。これが、長期テストを行った理由です。

調査の結果、「Aw Snap」ページを診断するには、Google Chrome のログを確認する以外に方法がないようです。「Aw Snap」ページが表示されたときに異常なことは何も表示されなかった詳細ログで Sawbuck を使用してみました。

dom から要素を削除し、コードをコメントアウトし、css スタイルを削除し、考えられるすべてを試して、この問題の根底に到達しようとしています。そのすべてが失敗しました。

次のステップとして何が良いか知っている人はいますか?Chrome の Aw Snap ページの原因は何ですか? それはjavascript呼び出しである可能性がありますか、それともDOM操作が原因である可能性がありますか? どんな助けでも大歓迎です。

アップデート:

Windbg でダンプ ファイル (コメントに記載) をロードすると、例外が発生した場所のこのコール スタックが得られます。.ecxr コマンドを実行すると、次のようになります。 up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206 17b12d23 テストバイト ptr [eax+0Ch],4 ds:002b:1a30000c=?? コール スタック: 警告: フレーム IP が既知のモジュールにありません。次のフレームは間違っている可能性があります。

更新 #2:ericb の要求に基づく:

タイマー機能:

$.ajax({
        url: aUpdateUrl,
        type: 'post',
        success: function (aData) {
            try {
                if (self.IsAutoUpdating) {
                    self.OnBeforeDataUpdated();
                    self.Data(aData);
                    self._setUpdateTime();
                    self.DataRefreshed = true;
                    self._applyAutoSizing();
                }
            }
            catch (error) {
                self.Widget.HandleError(error);
            }
        },
        complete: function () {
            self.Widget.Loaded = true;
            if (self.IsAutoUpdating) {
                self.AutoUpdateTimer = setTimeout(function () {
                    self.StartAutoUpdate(self.AutoUpdateUrl);
                }, self.UpdateInterval);
            }
        }
    });

完全な関数は、テストのために 5 秒に設定された self.UpdateInterval 時間で再度呼び出されるようにタイマーを設定します。

さらに、ここに html と、それをノックアウトに接続する方法を示します。

<div id="notifications-@Model.Key" class="notification-items">

<ul data-bind="foreach: { data: Dashboard.WidgetLayer@(Model.Key).NotificationModel.notificationsToShow,
    afterRemove: Dashboard.WidgetLayer@(Model.Key).NotificationModel.hideNotificationElement,
    afterAdd: Dashboard.WidgetLayer@(Model.Key).NotificationModel.showNotificationElement }">
    <li class="notification-item group" data-bind="click: Dashboard.WidgetLayer@(Model.Key).NotificationModel.onNotificationClick">
        <div>
            <img class="notification-icon" data-bind="attr: {src: Spec.Icon}" alt="icon"></img>
        </div>
        <div class="notification-content group">
            <div class="notification-header">
                <div class="title">
                    <span class="subject-name" data-bind='text: SubjectTitle'></span>:&nbsp;<span class="spec-title" data-bind='text: Spec.Title'></span>
                </div>
                <button class="acknowledge-notification" data-bind="click: Dashboard.WidgetLayer@(Model.Key).NotificationModel.acknowledgeNotification, clickBubble: false"></button>
                <div class="time-since-event" data-bind='text: FormattedTimestamp'></div>
            </div>
            <div>
                <div class="spacer"></div>
                <div class="details action-details" data-bind='text: Details'> </div>
            </div>
        </div>
    </li>
</ul>

また、次のようにフェードイン/フェードアウトを使用して、通知 div に jquery ライブを設定しています。

$('#notifications-@Model.Key .notification-item').live({
        mouseenter:
            function() {
                var lElement = this;
                $(lElement).find('.time-since-event').stop(true, true).fadeOut(0, function (){$('.acknowledge-notification', lElement).fadeIn(2000);});

            },
        mouseleave:
            function() {
                var lElement = this;
                $(lElement).find('.acknowledge-notification').stop(true, true).fadeOut(0, function (){$('.time-since-event', lElement).fadeIn(1000);});
            }
    });

通知リストを更新する JavaScript コードの残りの部分は、http: //knockoutjs.com/examples/animatedTransitions.htmlで入手できる、アニメーション化されたトランジションのノックアウト js のライブ サンプルに基づいています。

必要に応じてそのコードを提供できますが、150 行あり、簡潔にするために除外することにしました。

4

2 に答える 2

1

たぶん、別のポーリング技術を見たいと思うかもしれません。ユーザーの数に応じて、Signalr を検討することをお勧めします。

https://github.com/SignalR/SignalR

私は最近、signalr と knockoutjs を統合する方法について講演しました。

スライドと例: http://bit.ly/FamilyFeudSlides

コード: https://github.com/jasonmore/familyfeud

于 2012-04-18T16:26:12.843 に答える
0

原因は、最適化エンジンにある可能性があります。

私も同様の問題を経験していましたが、V8 最適化エンジンによって引き起こされた Aw Snap クラッシュに切り分けることができました。繰り返し実行される〜2400行の大規模な機能がありました。関数が 300 回程度呼び出された後 (数は、他の一見無関係な変更によってかなり異なります)、最適化エンジンが作動し、Windows タスク マネージャーは RAM 使用量に大きなスパイクを表示し、「Awタブの「スナップ」。

フラグ --js-flags="--allow-natives-syntax" を指定して Chrome を起動すると、ネイティブの V8 javascript コマンド%NeverOptimizeFunction(functionName);を使用して、Chrome がオプティマイザを実行するのを防ぐことができます。

ご想像のとおり、これは追跡するのが最も簡単なバグではないため、恐ろしい「Aw Snap」の潜在的な原因として考慮すべき別のことの提案としてこれを追加するだけです.

于 2015-10-07T17:41:40.483 に答える