web-dev-qa-db-ja.com

JavaScriptはGCコレクションを強制しますか? /強制的にオブジェクトを解放しますか?

私は、オーディオインターフェイスを使用して任意のサウンドを再生するためのjs関数を持っています(すべての呼び出しに対して新しいインスタンスを作成します)。

これは、32回目の呼び出しが行われるまで(場合によっては少なくなる)、かなりうまくいきます。この問題は、Audioインスタンスのリリースに直接関連しています。私はこれを知っています。ChromiumのGCを実行するための時間を確保し、さらに32音ほど再生できるようにするためです。

これが私がやっていることの例です:

<html><head>
<script type="text/javascript">
function playSound(url) {
    var snd = new Audio(url);
    snd.play();
    snd = null;
}
</script>
</head>

<body>
<a href="#" onclick="playSound('blah.mp3');">Play sound</a>
</body></html>

私はこれも持っています。これは、playSound呼び出しが32未満のページでうまく機能します。

var AudioPlayer = {
    cache: {},
    play: function(url) {
        if (!AudioPlayer.cache[url])
            AudioPlayer.cache[url] = new Audio(url);
        AudioPlayer.cache[url].play();
    }
};

しかし、これは私がやりたいことでは機能しません(divを他のコンテンツ(動的に別のファイルから)に動的に置き換えます)。さらに多くのサウンドが含まれています-1.メモリ使用量は簡単に急上昇します。

すぐに音を出す方法が必要です。これは可能ですか?オーディオインターフェースのfree/close/unloadメソッドが見つかりませんでした。

ページはローカルで表示されるため、サウンドの継続的なロードは大きな要因ではありません(ほとんどのサウンドはかなり短いです)。

25
komiga

これは完全な答えではありませんが、「chrome jsエンジンにガベージコレクションを強制する方法はありますか?」、 a chromium.orgの人からの回答 =:

一般的には、仕様ではありません。テストの目的で、コマンドラインに渡してJavaScriptコマンド「window.gc( ) "ガベージコレクションを強制します。

--js-flags '--expose_gc'


UPDATE:ただし、@ plash のコメントに記載されているように、このフラグはデバッグビルドでのみ機能します。

17
Daniel Vassallo

少なくとも1つ(または2つ)の欠陥があります。

snd = new Audio(url);

の前にvarがないため、sndがグローバルスコープに割り当てられます。それは通常あなたが望むものではありません:それはグローバル名前空間を乱雑にし、別のスクリプト(例えば拡張機能)が偶然sndを使用する場合、物事は混乱します。

そしてそれがまた理由です

delete snd;

動作しません: グローバル変数を削除する

宣言された変数と関数がVariableオブジェクトのプロパティになると(アクティベーションオブジェクト(関数コードの場合)またはグローバルオブジェクト(グローバルコードの場合))、これらのプロパティはDontDelete属性

だから、使用

var snd = new Audio(url);

代わりに。ところで、JavaScriptエンジンにガベージコレクションを強制することはできません。

20
Marcel Korpel

削除してnullに設定するだけでも機能しなかったため、回避策を講じました。

同時に複数のサウンドで機能します。インスタンスを解放するには、すべてのサウンドがオブジェクトタグである必要があります。動的に、すべてのオブジェクトタグ(サウンド)をDivに追加します。インスタンスを解放するには、Divから動的にオブジェクトタグ(サウンド)を削除します。

私は推測これが機能するのは、ブラウザが通常各タグを何らかのオブジェクトとして実装しているためです。したがって、タグを削除すると、内部オブジェクトが削除され、それに関連付けられているすべてのリソースが解放されます。

<!--HTML: This will contains object sounds-->
<Div id="sounds"></Div>

//Javacript, using jQuery
//Create and play an MP3
var id_event = 1234; //Keep and incrementing a counter might do, I use an Event Id from my app.
var objSound = "<object width='1' height='1' id='AUDIOIE" + id_event 
        + " type='application/x-oleobject'  AND_MORE_PARAMS_TO_PLAY_A_MP3"
        + "/>";
$(objSound).appendTo('#sounds');

完全なオブジェクトパラメータについては、 ここ にアクセスしてください。

//To Stop an MP3 and release it instance.
$('#AUDIOIE' + id_event).empty().remove();
2
user347594