2015年4月30日木曜日

Windows8.1 消せないTSファイル

表題、正確には「アクセスするとシステムの負荷が極めて高くなり、かつその状態が長時間つづくTSファイルがある」です。

前置きです。
今日、午前中に完了しているはずのwbadmin.exeによるバックアップが「アクセス拒否」によって失敗していました。

どこにアクセスしようとして、いかなる理由で拒否されたのかは言わず、ただ「アクセス拒否」。
もう、windowsに限った話ではありませんが、ほんと最近の「お前ら愚民にはどうせ理由なんか言ったってわかんねえだろ?結果だけ知らせるだけでも親切と思え」っていう設計思想、真面目に何とかなりませんかねえ。
それでもなお、管理者向けツールだという自覚があったらしく、エラーログが保存された先はここです、というメッセージが出ていたのでさっそく参照してみると、そんなファイルはそもそも存在していない、とまあ、そんな体たらく。
作成する以前に失敗したのか、エラーログを作成しようとして失敗したのかはわかりませんが、結局再起動後手動で実行させてみたら今度は正常に処理を開始しました。

確かにどんどんOSの品質も上がってきていて、その恩恵にあずかること大です。
しかしNT3.5から何年たっても「何だか知らないけど再起動したら成功した」とかいうトラブルが残り続けているくせに、やれNT4.0だ2000だxpだvistaだ7だ8だ8.1だ挙句に10だお前ら買え!但し1年間だけ待ってやる!!とかもう。
再起動が必要なシステムトラブルが発生したらユーザに通知できるような保護機能って、現在のNTのアーキテクチャじゃ難しいんですかねえ。
必ず何らかのプログラムが動作した結果がそういうトラブルを発生させているわけですから、理論上は可能ですよね。まあ、宇宙線によるデータ化けっていうことも現実にはありますし、それ以前にDRAMは実際にはかなりエラーレートが高いのですべてOSで何とかせよ、というわけにもいかないことはわかりますが、以前にも指摘というか愚痴った通り、不適切なエラーメッセージが多すぎるのは確かで、まずそれを改善したうえで、すべからくOSとして期待される機能が確実に動くようにしてもらいたいところです。
それとも、原因はどうあれ、再起動すりゃいいんだからそんな機能を実装するコストなんか省こうぜ、という考えなのかもしれませんが。

こんなことがあったので、以前体験したトラブルを思い出しました。
バックアップ中でもあり退屈なので、恥の記録を残しておきたいと思います。
そこで、本題に移ります。

以前、特定のMPEG-2 Transport Stream(以下TS)を保存したファイルが消せないという問題に突き当たりました。

  1. エクスプローラでゴミ箱に
     ->削除の準備画面が出たまま停止し、ゴミ箱に入らない
  2. cmd.exeからdelコマンドで直接削除
     ->delコマンドが応答しなくなる
  3. エクスプローラで直接削除
      ->削除の準備画面が出たまま停止し、消えない
  4. エクスプローラ上から当該TSファイルをクリックして選択する
      ->選択しただけで追加で発生する現象(後述)が発現する。
とまあ、こんな具合です。
要するに、最初は削除しようとして顕在化したこの問題は、4番目の現象から、ただアクセスしただけで発生するということがわかりました。
さらに、上のすべてで追加で発生する現象として

  • メモリがどんどん消費されてゆく
  • OS全体の動作が急に重くなる

という点が特徴的です。
なんだかext2/3/4の大きいファイルの削除時の挙動に似ていますが、あちらはファイルシステムの構造そのものが原因ですので、関連性はありません。

なお、念のためLAN経由でほかのマシンにある同一のファイルにアクセスしてみると、この問題は起きませんでした。
ローカルに接続されているストレージに保存されているファイルにのみ発生する問題でした。

エクスプローラの場合、一度TSファイルをクリックしたり、削除作業を開始した旨の例の進捗グラフ付きの画面が出たまま停止してしまったら最後、削除のキャンセルを行い再度削除しようとしても、エクスプローラを再起動して再度削除を試みても「ファイルが使用中」となって削除できません。おまけにOSの動作が異常に重くなるという害まで出てきてお手上げ。

再起動すると、やはり削除は行われておらず、再度削除を試みても上のとおりになる。
もう面倒になってほっといたら、大変な時間がかかってはいるが、最終的にはゴミ箱に入ることがわかりました。
一度ゴミ箱に入っても、「ゴミ箱を空にする」コマンドで消去を試みるとまた上記のような状況に陥りますが、やがてこちらもいずれは削除が完了することがわかりました。

とはいえ、やがて消えるからいい、というわけにもいかず、消去作業の間、OSが重くて使い物にならなくなるのは困ります。
困るというのは、重くなると、WindowsのようなデスクトップOSの場合は、各アプリケーション製作者自身や、アプリケーションの動作前提となるプラットフォームやライブラリそのものがタイムアウト時間などを思い込みで作っていたりするようなしょぼい設計のアプリケーションが非常に多いので、こういう高負荷状態が一定以上続くような場合に余計なトラブルをさらに呼び込む結果につながるためです。

特定のTSファイルに限ってこの現象の再現性は100%のため、テスト自体は楽なので、何らかの原因があるはずだと思って暇なときに調べてみました。

まず最初にゴミ箱そのものを削除して再生成させてみましたが、結果は変わりませんでした。

まあ、ダメ元でやったのでゴミ箱の件はどうでもいいとして、まず、削除しようとしたときに誰かがファイルを掴んだままとなるために、2回目に同一ファイルを削除しようとすると排他されて「使用中だよ」と怒られることから、誰かが何かをしようとしていることは察せられます。
以前のOSで、画像がらみのトラブルとして、エクスプローラが頼みもしないサムネイルづくりに精を出して、エクスプローラ自身が掴んだままになるために同じような現象になる例があったのを思い出して、タスクマネージャでエクスプローラの挙動を観察していると、エクスプローラ自身はCPU利用率もメモリ使用量もディスクアクセス頻度も増加しないという観察結果になり、さらに、エクスプローラを再起動してもファイルが使用中のままになる、delコマンドでも同じようなことになるという点から考えても、他のプログラムが掴んだまま離さないということがわかりました。

アンチウイルスらしいのでいかにも悪さをしそうだということで、次に疑ったのはWindows Defender。しかしこちらも観察してみると何もしておらず、潔白でした。

それでは誰がメモリを食って大量のディスクアクセスを行っているのか調べるため、タスクマネージャでは得られる情報に限りがあるので、今度はリソースモニタで観察していると、削除できないTSファイルにものすごい勢いでアクセスしていたのは「System」。要はカーネルが直接つかんでますよ、と。

これはまた面倒くさいプロセスに掴まれたもんです。
こいつは.sysの集合体の面があり、リソースモニタでもどの.sysが悪さをしているのかまでは判別不能です。なんでもかんでも十把一絡げににされてしまうとこのざまです。
こうなると、sysimternalsの定番、Process Exprolerが必要になります。久しぶりに最新版を探してインストールすると、幸いWindows8.1でも動作してくれたので、早速観察していると、どうもdxgmms1.sysのVidMmInterfaceスレッドが原因のようです。
dxgmms1.sysはDirectX Graphics MMSだそうで。MMSってなんですかねえ。

とはいえ、カーネルレベルで、おまけにいつものトラブルの定番といった印象のあるDirectX様が掴んでいるということはわかりました(大抵VGAドライバが悪いんですけどね)。掴む対象がTSファイルなのでDirectXが顔を出してきても不思議ではないのかもしれません。

まあ、こういう手合い(VGAがらみ)は手を付けると大火傷をするので、あまり関わりたくはないのですが、ただ、極端に重くなるのは困りますので対処療法を考えます。

さて、このVidMmInterfaceスレッドにファイルを渡すのはエクスプローラを経由せずにcmd.exe経由でdelコマンドを発行してもこのスレッドが動くということから、対象のTSファイルにアクセスした段階でカーネル自身がこのスレッドに渡しているということのようですね。
私はエクスプローラではサムネイルを表示させない設定にしてあるし、フォルダの表示方法も「全般」にしてはあるのですが、もうエクスプローラがどうのこうのという問題ではないのでしょうね。何かほかの理由があってどうしても解析せずにいられないのかもしれません。フレームレートとかわからないと悔しくてしょうがないとか。

とにかくシェルを問わずファイルへのアクセスの段階でTSファイルの解析処理は必ず実行されてしまうものと見えます。困った設計ですねえ。われら愚民に(やらなくていいことを)偉大かつ寛大なるマイクロソフトさまによりご親切にもご優渥にも(言われてもいないのに)処理して下さるという、いつものパターン。
その処理をOFFにする設定さえ見つかればすべて解決なのですが、遺憾ながら今なお見つけることができていません。

また、観察していると、すぐにシステムが重くなる原因もわかりました。
ひたすら削除に時間がかかるTSファイルは、おそらくこのスレッド様が期待した形式ではないと見え、特定のTSファイルをひたすら読み込んでいきます。

どうもハンドルから見るとメモリマップドファイルとしてではなくReadFileしてるものらしい。うへぇ。とにかくファイルを実メモリ、仮想メモリの区別なく、すべてメモリとして利用できる上限までリードしようとするため、読み込み量が実メモリを超えた瞬間、ページファイルにほかのプログラムがどんどん追い出されていきます。かつ、自分自身の先に読んだメモリもページファイルに送られていきます。

すると、当然ですがものの見事にスラッシングが始まります。これが動作が重くなる原因です。
いまどきスラッシングを体験するとはなあ。懐かしいなあ。

TSファイルサイズは、おおよそ1時間で5~6GBですから、大抵の場合実メモリの範囲内で収まっていたため、速度の低下が顕在化しなかっただけで、実際にはしょっちゅう解析できないTSファイルは生成されていたものと思われます。
顕在化したのは、件のスレッドが理解できない形式で生成されたTSファイルのサイズがたまたま巨大だったためでした。他の巨大なTSファイルでも、このスレッドが理解できる形式と思われるファイルであれば瞬時に処理が終わるため、理解、解析ができない間はひたすら読み込んでしまうという仕様のようです。
このような理由から、Windows7の64bit版では同様な現象が起こるでしょうが、32bit OSではこの問題は発生しないかもしれません。
実際、買い替え前のVistaが32bitでしたが、このような経験をしたことはありませんでした。VistaにそもそもVidMmInterfaceスレッドに渡す、という処理がなかったかもしれませんから、まあ知れたものではありませんけどね。

どういう形式のTSファイルが理解できないのか調べようか、とも思いましたが、たまにしか作られないということもあり、さらにTSファイルが生成される前に形式がわかるわけでもなく、わかっても保存するかどうか選別できるわけでもないのでやめました。

さて、そのTSファイルは仮想メモリ以上のサイズだったのですが、メモリ不足によってOSが落ちるということはありませんでした。
メモリ確保APIの戻り値を見ない阿呆(ものすごくよくある風景)が作っていたらえらいことでしたが、落ちないということは、最低限のエラー処理は行っているようです。要は、全部読み込む必要はないけどメモリがあるならいいじゃん、使っちゃおうぜ、ってことのようです。
それができるならバッファサイズを超えたら解析をあきらめるとか、先読みしたデータを破棄することができるはずなのに、その点は完全に手抜きですね。まさか解析できないファイルがあるとか、数十GBものサイズがあるファイルがこの世に存在するとか、設計者には想像もできない事態だったのでしょう。仕様バグですね。

そこで、対処療法としては、スラッシングが起きるのは仮想メモリが存在するからなので、仮想メモリを外して(pagefileをなしにして)テストしてみると、実メモリ内でやりくりするので、すべてのメモリを使い切る、という点は同じですが、極端な動作速度の低下はなくなりました。

とにかく一度そんなTSファイルができてしまうと、うっかり一度触れたら最後、アクセスが終了するまでひたすらスラッシングに耐えるか、あるいは強制停止するにはリブート以外に道がないので、今のところ、まあ、削除時にとっとと終わってくれるなら、これでイイヤ、ってなところです。

抜本的な解決を見つけたら書こう、と思っていてすっかり忘れていたのを、冒頭の理由でふと思い出したので、それっきり抜本的な解決策を探さず放置しているので、ここで一回書いてみました。

どこかのオプションをON/OFFすればあっさり片付くような気もして仕方がありませんが、恥ずかしながらいまだに見つけられていないのは前述のとおりです。

解決策を求めてこられた方には申し訳ありません。

なお、バックアップ処理は何時間も前に正常に完了いたしました。

13 件のコメント:

  1. 直ってると思って10プレビュー入れましたが全く同じでした

    返信削除
  2. 情報ありがとうございます。
    MSは問題の認識をしているかは定かではありませんが、この件は日本の、さらには特定の放送局の固有の問題ですから、対応するコストに見合わないので、せいぜい「マイクロソフトはこの問題を認識しており、現在対応を検討中です」と言ってくれれば上出来、というところでしょう。
    やはり、解析を行わないようにさせる手段を探したほうが現実的だとは思いますが、面倒なので相変わらず放置しています・・・申し訳ございません。

    返信削除
  3. その後これで起こらなくなりましたので是非お試しください
    699 :名無しさん@編集中:2014/12/11(木) 14:41:16.33 ID:VRG+Y64n

    ShellExViewで「MF MPEG Property Handler」あたりをdisableにすれば良いんじゃ?

    返信削除
  4. 有益な情報をありがとうございます。
    現在手元に問題が発生するファイルがないので、できたら早速試してみたいと思います。

    返信削除
    返信
    1. 今まで、ゴミ箱にも右クリックしてもエクスプローラーが固まってたファイルがつかめるようになりました。情報ありがとうございます。

      削除
  5. 横レスすみません。
    自分もテレ東のtsファイルを削除できなくてここに辿り着いたのですが
    匿名様の通りShellExViewで弄ったら無事削除移動できるようになりました
    情報ありがとうございました。

    返信削除
  6. お初です(念のため)2015年11月17日 18:56

    特定チャンネルというわけではないんですが、大量(数百ギガバイト)のts群を移動したら重くなる現象が発生しなくなりました

    このページのみなさん、ありがとう

    返信削除
  7. 長い間原因不明で困っていた不具合が解決できました。本当に助かりました。ありがとうございました。

    返信削除
  8. Windows7 から windows10 へ移行して以来数ヶ月、直下にTSファイルを置いていたHDDを開けるのに長時間(一時間以上?)掛かり、メモリも消費し尽くしてしまうという現象に悩まされていました。このページを読み、匿名さんの「ShellExViewで (MF MPEG Property Handler) をdisableにする」を実行したところ不具合が解消しました。 匿名さん、ayumiさん、本当に助かりました。ありがとうございました。

    返信削除
    返信
    1. 自己返信、部分修正です。
      エクスプローラーの操作上は確かに不具合が解消したのですが、他のソフトのファイル選択画面では以前と同じ症状のままでした。例えば、TVTest.exe, HDTVtoMPEG2.exe, Mpeg2Repair.exe などのファイル選択画面ではメモリ全部消費、ディスク負荷100%になってしまって動かなくなります。

      削除
    2. 通りすがりの人2016年6月26日 21:49

      Property Handler には、64bit と 32bitがあるので、ShellExViewのオプションで、
      Show 32-bit Shell Extensions にチェックを入れた状態で、MF MPEG Property Handler を無効化してやれば良いみたいです。
      (おそらく、TVTest.exe, HDTVtoMPEG2.exe, Mpeg2Repair.exe は、32bitアプリなのでしょう)

      削除
  9. Windows8.1のPCで発生していた問題(特定のtsファイルでエクスプローラが応答なしになる)がようやく解決しました!
    情報ありがとうございました。

    返信削除
  10. 通りすがり2021年8月15日 22:14

    >>ShellExViewで「MF MPEG Property Handler」あたりをdisableにすれば良いんじゃ?

    解決策が分からず、ずいぶん遠回りをしましたが、もう6年も前にこんな解決策が提示されていたのですね。
    ShellExViewで一発で直りました。
    感謝してもしきれません。ありがとうございました。

    返信削除