54

この単純なバッチ ファイルは、比較的短い順序で実行され、Windows 7 (x64) で使用可能なすべてのメモリを消費します。どうしたの?また、それを防ぐためにどのような予防策を講じることができますか?

any-invalid-command-you-like-here ^

効果を発揮するために明らかに必要な前提条件:

  • キャレット^はファイルの最後の部分であり、スクリプトは改行で終了していません
  • キャレットの前に少なくとも 2 つのスペースまたは文字があります。たとえば、次のドットがスペースを表している場合、メモリ リークは発生しませんが.^、これは..^(ゆっくりと)発生します。

このProcess Explorerのスクリーン ショットでは、スクリプトは約 30 秒間実行され、2.9 GB を消費し、一定の速度で上昇していました。

2.9GB のメモリが消費され、まだ上昇中

これを試してみる場合は、[ウィンドウを閉じる] [X] コントロールを取得できることを確認するか、タスク マネージャーまたはプロセス エクスプローラーを起動して準備ができていることを確認しCtrl-CくださいCtrl-BreakAlt-F4

複数のキャレットを使用すると、メモリ使用量がはるかに速く増加するようです。初めてこれに遭遇したときは、1 ~ 2 分で十分なメモリがなくAlt-Tab、3 本指の敬礼でさえCtrl-Alt-Del効果がありませんでした。マシンの電源を切らなければなりませんでした。

4

1 に答える 1

45

考え

これの原因は (私の理解では)、cmd インタープリターがエスケープする文字を探しているためです。これ^は、バッチ エスケープ文字であるためです。このシナリオでは、ファイルの終わりを適切に識別する代わりにeof、cmd は、エスケープする文字を探している間、ループして何かを初期化し続けます。

Windows 8 Pro (64) でcc^^^(リークを高速化するために複数のキャレットを使用) で再現。

試練

cc^無限ループと非常にゆっくりとリークします。

cc^^通常の無効なコマンド エラーでクラッシュします。

cc^^^無限ループとリークが速くなります。

cc ^無限ループと非常にゆっくりとリークします。

cc ^^通常の無効なコマンド エラーでクラッシュします。

cc ^^^無限ループとリークが速くなります。

cc"^通常の無効なコマンド エラーでクラッシュします。

cc"^^通常の無効なコマンド エラーでクラッシュします。

cc"^^^通常の無効なコマンド エラーでクラッシュします。

ノート

  • キャレット^が文字通り (引用符の外で) 使用されている場合にのみ、無限ループとリークが発生します。引用を追加すると、標準の無効なコマンド エラーでスクリプトがクラッシュします。
  • バッチ ファイルがUTF-8またはASCIIとしてエンコードされている場合のみ、無限ループとリークが発生します。UTF-16の場合、スクリプトは標準の無効なコマンド エラーでクラッシュします。
  • 最後のキャレットをエスケープしないように、キャレットの数は奇数でなければなりません。

予防

  • キャレット^(0x5E) または少なくとも奇数のキャレットで終了するバッチ スクリプトがないことを確認します。
  • または、UTF-16 でエンコードします。
于 2013-03-18T03:15:07.043 に答える