14

ドラッグアンドドロップと複数の選択ファイルを使用してサーバーに画像をアップロードするためのHTMLインターフェイスを作成しています。サーバーに送信する前に画像を表示したい。だから私は最初に使用しようとしましたが、この投稿FileReaderのようにいくつかの問題がありました。だから私は自分のやり方を変えて、ebidelが投稿で推奨しているようにblob:urlを使用し、メモリを解放することにしました。window.URL.createObjectURL()window.URL.revokeObjectURL()

しかし今、私はこれに似た別の問題を抱えています。クライアントが必要に応じて一度に200枚の画像をアップロードできるようにしたいと思います。しかし、ブラウザがクラッシュし、使用されたRAMが非常に高かった!そこで、同時に表示される画像が多すぎるのではないかと思い、一度に10個のファイルしか処理できないように、配列を使ってファイルの待機キューを設定しました。しかし、それでも問題は発生します。

Google Chromeでchrome://blob-internals/、ファイル(通常はによってすでにリリースされているwindow.URL.revokeObjectURL())を確認すると、約8秒の遅延後にリリースされます。Firefoxの場合はわかりませんが、ファイルがリリースされていないようです(about:memory->画像をチェックします)

私のコードは悪いですか、それとも私とは無関係の問題ですか?ナビゲーターにメモリをすぐに解放させる解決策はありますか?それが役立つ場合、これは問題が発生するJavaScriptの一部です:コードが質問に含まれていなかったため、リンクが期限切れになりました

編集

これは一種の独自の回答+bennlichへの回答です(コメントするにはテキストが長すぎます)

user1835582の回答から、Blob / Fileを実際に削除できることがわかりましたが、ブラウザーには画像が必要ですが、画像はメモリ内のどこかに保持されます(これは論理的です)。ですから、方法ではなく、クラッシュとスローダウンを引き起こした画像(多くと重い)を表示するのは事実revokeObjectURLです。さらに、各ブラウザは独自の方法でメモリを管理するため、動作が異なります。これが私がこの結論に至った経緯です。

まず、 https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example.3A_Using_object_URLs_to_display_imagesrevokeObjectURLのソースコードを使用した簡単な例を使用して、これがうまく機能することを試してみましょう。Chromeを使用すると、表示された画像をチェックするか、空白の新しいタブで開こうとすることで、Blobが適切に取り消されていることを確認できます。注:Blob参照を完全に解放するには、を追加します。数年前に質問を投稿したとき、blobをリリースするのに約8秒かかりましたが、今ではほぼ即時です(おそらく、Chromeやより優れたコンピューターの改善によるものです)。chrome://blob-internals/document.getElementById("fileElem").value = ""

次に、充電テストの時間です。私はそれぞれ約2.5Moの100のjpgでそれを行いました。その画像が表示された後、私はページをスクロールしました。Chromeがクラッシュし、Firefoxが低速でした(他のブラウザではテストされていません)。しかし、私がコメントしたときli.appendChild(img)、大量の画像があっても、すべてうまくいきました。これは、問題がrevokeObjectURL実際に適切に機能する方法に起因するのではなく、多くの重い画像を表示することに起因していることを示しています。また、何百もの重い画像を含む単純なhtmlページを作成してスクロールすることもできます=>同じ結果(クラッシュ/スローダウン)。

最後に、画像のメモリ管理について詳しく調べるために、Firefoxでabout:memoryを調べるのは興味深いことです。たとえば、ウィンドウがアクティブな場合、Firefoxは画像を解凍します(画像->非圧縮-ヒープが上がります)が、raw(画像-> raw)は常に安定しています(読み込まれた画像の量に対して)。ここにメモリ管理についての良い議論があります:http://jeff.ecchi.ca/blog/2010/09/19/free-my-memory

4

2 に答える 2

6

window.URL.revokeObjectURL ()を使用すると、 [Blob]または[File]オブジェクトのみを取得できます。メモリから強制的に削除することはできません。

ノート。 ブラウザは確定されておらず、これらの機能からリークする可能性があります。アニメーションを実装する場合は、自己責任でそれを理解する必要があります。

于 2012-11-19T13:26:16.163 に答える
2

これは答えではありませんが、私が知る限り、これはChromeの最新バージョン(35)でもまだ問題であると言いたいです。問題を明らかにするテストページを作成しました。

http://ecobyte.com/tmp/chromecrash-1a.html

コンピューターで高解像度の写真を多数(たとえば600枚)選択してそのページのボックスにドロップすると、Chromeがクラッシュします(Windows7およびMacOS X 10.8.5で試してみました)。

ソースを見ると、一連の操作が次のようになっていることがわかります。

  1. createObjectURL
  2. imgをロードします(DOMに追加しないでください!)
  3. revokeObjectURLを使用して、参照を解放します
  4. imgrefを失う
  5. 次にドロップする画像に対してすべての手順を繰り返します

いつでも1つの画像だけがメモリにあるか、参照されているように見えますが、最終的にはChromeがクラッシュします。

于 2014-05-22T15:15:44.243 に答える