none
IE11メモリー増加 RRS feed

  • 質問

  • マイクロソフトコミュニティより有効な情報がありませんでしたのでこちらに投稿させていただきました。

    本文はそのままコピーしてきておりますのでお気づきの点などありましたら書き込みお願いいたします。

    色々と調べたり試したのですが中々解決が出来ない為投稿させていただきました。

    PC環境

    Windows7 32bit

    IE11

    通信ライブラリ prototype.js

    内容はIE11上でAjax通信を行っているとメモリが増加するという現象です。

    IE11に特定している理由は全く同じスペックのPCでIE8では発生しないからです。

    毎回通信を行った後にメモリが増加するなどであれば処理などに問題があると見てリーク個所を特定していくのですが…

    通信回数1秒間に4回の間隔で行っており一定時間経過すると一気に増加します。

    計測結果数値(パフォ―マンスモニター iexplore#1 virtual Bytes)

    3/6 21:10  922.525.696(スタート)

    3/6 23:36  939.499.520

    3/7 20:50  957.128.704

    3/8 19:35  973.709.312

    この状況で考えられること、対策案がありましたらご教授ください。

    ※情報が足りない場合は追記致しますのでご指摘ください。

    宜しくお願い致します。

    2018年3月12日 11:25

回答

  • 確実な情報が必要であれば有償サポートへ.....と言いたいところですが、有償サポートに問い合わせても「納得がいかない」だけでは先に私が書いたのと同様の理由で調査されないと思います。使用メモリが増加することで実際に動作に支障が生じ、かつ支障が出る前に再起動することができない合理的な理由があり、さらにその支障により重大なビジネス インパクトがあることを示さないと調査に入ってすらもらえないでしょう。

    引き続きこのフォーラムで情報提供を求められるのは構いませんが、個人的にはあまり期待しないほうが良いと思います。


    hebikuzure

    • 回答としてマーク Dark5831 2018年3月14日 6:16
    2018年3月14日 5:07
    モデレータ

すべての返信

  • リークしてそうな感じはありますが、Internet Explorer はサーバー アプリケーションやサービスではないので、数日を超えるような長時間の連続起動は想定されていません。Inrernet Explorer を定期的に再起動する運用ができないか検討しましょう。


    hebikuzure

    2018年3月13日 8:01
    モデレータ
  • 返信ありがとうございます。

    おっしゃる通りなのですがそれでは根本的な解決になりませんので申し訳ない…

    システム的には一か月でIEの再起動をお願いしておりますのでそれまで動いていれば問題はありません。

    ただ、今回の原因を知りたくて投稿させて頂いております。

    普通定期的(右上がり)にリークしていくなら良いのですが約22時間位の間隔をあけて上昇していますので納得がいかないのです。

    IE11本体が何かしらの定期的な処理を行っていてそのタイミングで増加するなどの確実な情報があると嬉しいです。

    2018年3月13日 14:49
  • 確実な情報が必要であれば有償サポートへ.....と言いたいところですが、有償サポートに問い合わせても「納得がいかない」だけでは先に私が書いたのと同様の理由で調査されないと思います。使用メモリが増加することで実際に動作に支障が生じ、かつ支障が出る前に再起動することができない合理的な理由があり、さらにその支障により重大なビジネス インパクトがあることを示さないと調査に入ってすらもらえないでしょう。

    引き続きこのフォーラムで情報提供を求められるのは構いませんが、個人的にはあまり期待しないほうが良いと思います。


    hebikuzure

    • 回答としてマーク Dark5831 2018年3月14日 6:16
    2018年3月14日 5:07
    モデレータ
  • 自力で調べる根性があれば、の話ですが。。。。
    Process Monitor で、「一気に増加」するタイミングを含む期間。。。例えば「22時間位の間隔」で発生するなら、IE 起動後20時間~24時間の状態ををキャプチャして、メモリ使用量が「一気に増加」した時間帯に "iexplore.exe" プロセスがどんな処理を行っていたのかを調べれば、なにかわかるかも。
    ----------------------------------------------------
    Process Monitorのインストールからチィップスまで (1)
    http://troushoo.blog.fc2.com/blog-entry-68.html
    ----------------------------------------------------

    技術的な根拠が???な情報を求めるより、自分で調べた方がよっぽど確実。
    ちなみに私の仮想マシン上の Win7 x86 環境では、かれこれ1週間以上 IE を立ち上げっぱなしになってますが、特にメモリ リークが発生している様子はありません。
    IE8 では起きないとのことですが、もしかしたら 3rd ベンダー製アドオンの有無が影響しているのでは?
    2018年3月14日 6:07
  • hebikuzure様 返信対応有難うございました。

    やはりそうですか…以前別の内容で有償サポート受けたことあるのですが結局バグですとかで終わってしまったの諦めます。

    もし調査するとしても私個人でなく、大手企業さんにやって頂こうと思っています。

    残念なのがJQueryや個人で作ったXmlHttpRequest通信ロジックを使用したら起きませんよって話題が無かったことですかね。

    もし何かしらの対策が見つかったら記載しておこうと思います。

    有難うございました。




    2018年3月14日 6:16
  • 返信ありがとうございます。

    根性と言うなら…既に2週間調査や試験を行っています。(どうでもいいですけどね)

    アドオン系はすべて無効にしています。

    また、キャプチャーの時刻を見て頂くと判るようにIE起動後ではなくもしかするとPC起動後かもしれません…(調査中)

    一応現在試している及び変更した事を記載しておきます。

    IE11のXmlHttpRequest処理

    キャッシュコントロール機能が追加されているのでキャッシュのfalseを実行

    ※これにより右上がりにあがっていったメモリーリークが緩和

    IE11のHttp1.1クライアント上限を変更(効果調査中)

    通常Windows7は2つなので4に変更(レジストリ―: FEATURE_MAXCONNECTIONSPERSERVER)

    ※XmlHttpRequestが非同期で通信を行うのでほぼ同時に複数重なる場合がありました。

    2018年3月14日 7:01
  • これ1か月内にハングアップするなり正常に動かなくなるくらいに、永久に増えていくということでしょうか?

    IEのバージョンによってプロセスの構成や管理まで根本的に変わっていきますし、Scriptのエンジンも変わってますので、メモリ確保量の挙動がバージョン間で変わってもまあそれほど不思議でもありません。

    たとえば2GB位に行くまえにはどこかで一気に減るとか、それ以上増えなくなるとか、そういったことはないでしょうか?

    ※もちろん本当にそのまま延々と増えていくだけの可能性はありますが。

    2018年3月14日 7:23
  • 対策、調査以前の処理ですと永遠に増えていきIEがハングアップします。(20日位で白くなって固まる)

    その時の容量は2GBですね。

    OSがx64,x86どちらでも通常32ビットで動いてますのでその辺の仕様は昔から変わっていないと思います。

    現在8日稼働させっぱなしで

    Virtual Bytes  922.525.696→1.077.264.384

    30日到達時は今のままだと1.500.000.000前後だと思いますので1っか月は持つ計算にはなってるので大丈夫だとは思うんですけどね...

    実際に30日到達してないですし2GBまで増えていませんので何とも言えません



    • 編集済み Dark5831 2018年3月14日 8:06
    2018年3月14日 7:49
  • アドオンというより表示しているページ内の JavaScript の特定の処理でリークするというシナリオもありますね。これだと他の人の環境では問題なくとも、そのページを表示し続ける環境だと再現するでしょう。

    こちらは F12 開発者ツールで調査かな。


    hebikuzure

    2018年3月14日 8:03
    モデレータ
  • この辺りの制限でしょうね。


    hebikuzure

    2018年3月14日 8:08
    モデレータ
  • スクリプト内の処理の切り分けも行っています。

    ※ただprototype.jsを使用しているWebですので切り分けが簡単にはいかないと思ってます。

    スクリプト内変更して確認した結果

    1.タイマー処理を止める→リーク傾向無し

    2.Ajax通信を止める。→リーク傾向無し

    3.通信は行うがobject等の変更処理を行わない。→リーク傾向有り

    4.Ajax通信非同期を同期処理にする。→リーク傾向あり

    これから試そうと思っている方法

    1.XmlHttpRequestの処理を自作で作成し通信のみ行う。

    2.1で行った結果リークしない場合は各ファンクション呼び出しの処理を実行する。



    • 編集済み Dark5831 2018年3月14日 8:27
    2018年3月14日 8:23
  • > また、キャプチャーの時刻を見て頂くと判るようにIE起動後ではなく
    > もしかするとPC起動後かもしれません…(調査中)

    ログについて言及するなら。。。。
    パフォーマンス モニターで [iexplore#1 virtual Bytes] を監視しているようですが、[iexplore#1 Handle Count] や [iexplore#1 Thread Count] とかは監視していないんですか?
    プロセス内の仮想メモリ使用量が増えるのは、大抵の場合何かのオブジェクト (File, Thread, Process, Window, Device, etc.) を生成したときです。
    何かのオブジェクトを生成すると、そのオブジェクトを管理するためのハンドルが必要になり、そのオブジェクト ハンドルを用いて処理を行うスレッドも必要になる。。。。つまり仮想メモリの使用量の増加は、Handle Count や Thread Count の上昇を伴う場合が多いのです。
    で、仮想メモリ使用量の増加に伴い Handle Count や Thread Count が上昇しているのであれば、"Process Monitor" でそのタイミングの状態をキャプチャすれば何をしているのかわかる。。。かも、ということです。
    「2週間調査や試験」を行っても、技術的に根拠に基づいた調査をしなければ意味がないと思います。
    大切なのは、事実として何が起きているのかそれをきちんと把握して、その把握している事実に基づいて論理的な推論を立てることだと思います。

    ちなみに。。。。
    32ビット プロセスでは、PC に搭載されている物理メモリのサイズに関係なく、1つのプロセスに対して最大4Gバイトの仮想メモリ空間が割り当てられます。
    ですがこの4Gバイトのうち下位2Gバイト (0x80000000 - 0xffffffff) は、NT カーネルや各種ドライバが動作するカーネル モード側で使用されるので、アプリ等のユーザ モード側で動作するプログラムが利用できるのは、0x00000000 - 0x7fffffff までの2Gバイトまでです。
    仮に「一気に増加」する現象が、ユーザ モード空間の上限である2Gバイトで止まるのであれば、そのような「実装」になっている可能性も考えられると思います。
    (2Gバイトで止まらないのであれば、IE プロセスが落ちるかハングすることになると思います。)
    2018年3月14日 8:42
  • ご指摘有難うございます。

    iexplore#1 Handle Countやiexplore#1 Thread Countは確かに処理を行う際に必要なため増えますが正常時増加と減少を繰り返しております。

    現象が発生した後も上昇前と同じでしたので問題がないと記載をしておりませんでした。

    >大切なのは、事実として何が起きているのかそれをきちんと把握して、その把握している事実に基づいて論理的な推論を立てることだと思います。

    推測は色々立てているんですけどね…技術的面が足りないんでしょうね

    物理メモリに蓄積されているデータが仮想メモリに移動されてGBの処理が行われずにそのまま残ってしまっている?

    Ajax通信で取得しているデータが破損しており無いデータを参照してイベントやオブジェクトが破棄されずに残ってしまっている?

    windows updateの間隔で増えているのではないか?(windows7も行っているか不明です)

    https://social.technet.microsoft.com/Forums/ja-JP/9b8069c7-4e6a-492a-bdea-6bf37e0a6035/windowsupdate?forum=win10itprogeneralJP

    winhttpはHTTP1.1を使用していますのでその処理とAjaxが取り合いをしている?

    ただ、どれもHandle Countなどが上昇して見えるはずのものばかりですし、おまけにIE8では起きずにIE11で発生しているので困っています。

    一番初めに目に見えた動作の違いといえば起動時に

    IE8:iexploreとiexplore#1が立ち上がりiexplore#1が主で動作する

    IE11:iexploreとiexplore#1とiexplore#2が立ち上がり数秒経過後iexplore#2がiexplore#1に移行し動作を継続する。

    どれにしても勉強不足かなと思っております。



    • 編集済み Dark5831 2018年3月14日 14:46
    2018年3月14日 14:44
  • > 推測は色々立てているんですけどね…技術的面が足りないんでしょうね
    足りないんだったら補えばいいだけ。
    必要な知識をはじめから持ち合わせている人なんていません。
    足りないことに気づいたら、その都度足りない部分を補って、知識が蓄積されてくんです。
    足りない部分を補うことが「面倒だ」と思うのであれば、そこまでです。

    > 物理メモリに蓄積されているデータが仮想メモリに移動されて
    > GBの処理が行われずにそのまま残ってしまっている?
    この認識は間違いです。
    仮想メモリは物理メモリを補完するためのアーキテクチャですが、足りなくなった物理メモリを補うものではありません。
    Windows の世界で言われるガベージコレクションも、物理メモリに対するものではなく、仮想メモリに対するものです。
    そもそも今回の問題では、物理メモリは関係ない。
    先の返信でも書きましたが、
    32ビット プロセスでは、PC に搭載されている物理メモリのサイズに関係なく、1つのプロセスに対して最大4Gバイトの仮想メモリ空間が割り当てられます。
    つまり Windows 上のプログラムがアクセスできるのは、仮想メモリだけ。
    物理メモリのアクセスは NT カーネル経由でしかできない。。。。即ち物理メモリにアクセスできるのは NT カーネルだけ。
    各プロセス内の実行単位であるスレッドの処理は、仮想メモリに展開されているメモリ マップのうち、実行に必要な部分だけを物理メモリにコピー (ページイン) して処理を行ている。
    物理メモリにマップされた内容が必要なくれば、ページ ファイルに書き戻され (ページアウト)、物理メモリ上に次の処理のための空き領域が用意される。
    そもそも物理メモリ不足に陥ったら、アプリのハングなどというエラーでは収まらず、ブルースクリーンでシステム クラッシュです。

    > Ajax通信で取得しているデータが破損しており無いデータを参照して
    > イベントやオブジェクトが破棄されずに残ってしまっている?
    > windows updateの間隔で増えているのではないか?
    > (windows7も行っているか不明です)
    上記推測に関して、それを裏付ける客観的証拠はあるのでしょうか?
    無いのだったら、まずその先入観を捨てることをお勧めします。
    (個人的な経験では、闇雲に手あたり次第調べても、いいことありません。)
    2週間も悩んでいるのであれば、悩む前に、何に影響を受けているのかきちんと確認することが必要だと思います。
    先の返信では「アドオン系はすべて無効にしています。」とのことですが、"iexplore" や "iexplore#1" のプロセスに、3rd ベンダー製 DLL がアタッチしていないことは確認しているのでしょうか?
    アドオン系に限らずセキュリティソフト等も、ネットワーク通信やファイル I/O を監視するために、外部プロセスから "iexplore" プロセスに対して DLL インジェクションを行っていることがあります。
    それらインジェクションされた 3rd ベンダー製 DLL の不具合により、"explorer" や "iexplore" などのアタッチされた側のプロセスに問題が起きることはよくあることです。
    このような場合、上記で推測されている事案を調べたところで、原因にたどり着ける可能性はとても低い。
    そーいった「地道な」切り分け確認を行わず、自身に都合の良い飛躍した推測を基に調査をしているから、解決の糸口が見つからないんだと思います。
    (「約22時間位の間隔をあけて上昇」という現象が IE11 の問題であるならば、世界中で問題になっているのでは?)
    2018年3月15日 3:07
  • お二人とも情報提供とご教授有難うございます。

    一旦、私一人ではなく関係者集めて現状の報告と今後の対応を考えたいと思います。

    それにあたって一つ疑問があるのですが宜しいでしょうか?

    IE11上のHTTP1.1通信が平行同時処理が2つまでとなっておりますがこれをオーバーした場合はどうなるのでしょうか?

    検証すれば答えは出てくると思うのですがご存知でしたら教えてください。

    2018年3月15日 6:07
  • > IE11上のHTTP1.1通信が平行同時処理が2つまでとなっておりますが
    > これをオーバーした場合はどうなるのでしょうか?

    3つ目以降のコネクション要求は待たされるはず。
    ただし IE ではレジストリ設定で、3つ以上の同時接続も可能。
    -------------------------------------------
    Internet Explorer 11 への移行 – よくあるお問い合わせ ~ 最大同時接続数の増加 ~
    https://blogs.technet.microsoft.com/jpieblog/2016/01/26/internet-explorer-11-123-2/
    -------------------------------------------
    上記サイトで説明されているレジストリ設定で同時接続を3つ以上にした場合、RFC2616 での規定からはずれることになる。。。はず。
    (HTTP の同時接続数と今回の問題に、どんな関係性があるのか、私にはまったくわからない。。。)
    2018年3月15日 6:44
  • IE11のHttp1.1クライアント上限を変更(効果調査中)

    通常Windows7は2つなので4に変更(レジストリ―: FEATURE_MAXCONNECTIONSPERSERVER)

    Windows 7 / Internet Explorer 8以降のデフォルト値は 6 ですから 4 では制限をかけているだけですよ。
    2018年3月15日 6:45
  • 返信ありがとうございます。

    デフォルト値は確かに表記上は6みたいですが用意したWindows7は実際に覗いてみるとIE11は2でIE8は4になっていますので設計、記載者側の思惑に反しているのかもしれませんね。

    また闇雲って話に取られるかもしれませんがAjax通信をする上で関係性が全く無いって話にはならないかと思いますけど…

    2018年3月15日 8:34
  • 経験で言えば、同時接続数を RFC の規定以上に増やしたクライアントからアクセスした場合、実際に同時接続数が RFC の規定を超えるとその分の接続を拒否するサーバーは存在します(最近は滅多に見かけないけど、以前はよくあった)。

    クライアント側(IE)の挙動で言えば、スクリプトやユーザー操作のイニシエーションで、制限されている同時接続数を超えるようなサーバーへの接続が必要になった場合は、接続待ちのキューに入って空きを待つだけです。


    hebikuzure

    2018年3月15日 9:52
    モデレータ
  • デフォルト値は確かに表記上は6みたいですが用意したWindows7は実際に覗いてみるとIE11は2でIE8は4になっていますので設計、記載者側の思惑に反しているのかもしれませんね。

    Windows 7をインストールしただけで一切触っていないVMが手元にあったので確認してみました。もちろんIE11もインストールしていないのでIE8環境なのですが、当該レジストリは設定されていませんでした。

    この確認でわかったこととして、質問者さんの環境は追加のソフトウェア等によりInternet Explorerの設定をいろいろと弄られている可能性があります。こうなってくると、お馬鹿さんが言及されているように追加のソフトウェアによりDLLインジェクションされ、その影響でメモリリークしている可能性も出てくるかと思います。

    2018年3月15日 12:58
  • 皆様沢山のアドバイスなど有難う御座いました。

    問題が解決致しましたのでご報告させて頂きます。

    また、守秘義務などがありますので全てをお書き出来なかった事お詫び申し上げます。

    下記の処理方法が今回の増加原因でした。

    同じ過ちが他の方に起きる事は無いと思いますが皆様が似た処理を発見した場合はお気を付けください。

    ※回数にして約16万回位(22時間で1秒2回)呼び出せば現象が出ると思われます。

    function requestServer( sUrl, sFuncName ){
     var msec = (new Date()).getTime();
     new Ajax.Request(sUrl,
              {method: "get",
                parameters: "cache="+ msec,
                onSuccess:function(httpObj){eval(sFuncName)(httpObj,0);},
                onFailure:function(httpObj){eval(sFuncName)(httpObj,1);}
              }
              );
    }




    • 編集済み Dark5831 2018年3月30日 13:21
    2018年3月30日 13:18
  • これは sFuncName で渡される関数の処理内容に関わらず(例えば中身が空の関数でも)発生するということでしょうか?


    hebikuzure

    2018年3月31日 4:50
    モデレータ
  • そうですね。

    引数は関係ないですね。

    空の場合は行き先のfunctionが定義されないだけですし、実際検証していた処理では必ずsFuncNameが入っており正常、異常の処理が行われておりました。

    対処した個所はvar msec = (new Date()).getTime();をコメントにし、msec引き渡しをやめました。

    皆さんのほうが良くご存じだと思われますがprototype.jsの従来の使い方だと時刻を引き渡しキャッシュを無効にする手法が普通だったようですがIE11からキャッシュコントロールが変更になり従来の方法だと効果が無いみたいです。

    ライブラリ作成者には失礼な方法ですが引数の渡し方が分からない為、send直前に

    this.setRequestHeaders("Cache-Control", "no-cache");を追加させて頂きました。

    これで通信時のキャッシュも使わないようにしております。


    • 編集済み Dark5831 2018年3月31日 12:27
    2018年3月31日 12:06
  • いや引数が空の場合ではなく、引数に関数名は指定されているけれど、その関数はなんの処理もしないようなものでも、という質問です。


    hebikuzure

    2018年4月1日 1:16
    モデレータ
  • すみません。

    ご質問された内容で困っていますが…

    function requestServer( sUrl, sFuncName ){

      sFuncName = "test" ;
     var msec = (new Date()).getTime();
     new Ajax.Request(sUrl,
              {method: "get",
                parameters: "cache="+ msec,
                onSuccess:function(httpObj){eval(sFuncName)(httpObj,0);},
                onFailure:function(httpObj){eval(sFuncName)(httpObj,1);}
              }
              );
    }

    function test(httpObj,res){

    }

    これでも問題は発生しますか?ってお話でしたら発生します。



    • 編集済み Dark5831 2018年4月1日 6:41
    2018年4月1日 1:55
  • ああ、そういうことです。

    そうすると呼び出された関数側ではなく、呼び出し側の処理でリークしていると考えられますね。

    ありがとうございます。


    hebikuzure

    2018年4月1日 11:32
    モデレータ