firefoxとchromeのcanvas実験

おひさしぶりです。いきてます。そらんです。
最近HTML5canvasをいじってます。そこで気付いたことがあったので書きます。というか、ネタはすごい勢いで増えてるんですが、エントリを書く暇がないw

本題なのですが、canvasに画像を30fpsで描画するコードを書きました。
それを書いていてわかったことは、
ChromeはdrawImageを実行するたびにRAMを確保する。
FirefoxはsrcにURLをセットしてダウンロードさせているときにRAMを確保する
という挙動をすることです。どちらも本来のサイズよりかなり大きいです。そして30fpsで動かすと、これらがガベージコレクションが追い付かないまま進んでしまうので、すぐメモリを使いきってChromeならcanvasをロックして一切描画できなくなってしまったり、Firefoxならダウンロードが止まったり、ブラウザそのものが落ちたりします。
ここで、Firefoxは、500枚ダウンロードして、20秒待って…というコードをかいたところガベージコレクションが追い付くようになり、目的の挙動をするようになりました。
ただ、Chromeのほうはcanvasそのものへの制約なので、連続的なアニメーションを避ける以上の回避策は今の実装ではなさそうです。

ちなみにFirefoxはdrawImage中、とても安定して動作していました。

以下に、Firefoxでまともに動くCodeを。Chromeだと、単純ダウンロードの場合でもこの場合でも同じようにRAMを使いきった段階でcanvasがロックされてしまいます。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Hello, Woeld!</title>
		<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
		<script type="text/javascript">
		<!--
			$(document).ready(function(){
				init();
				
			});
			
			//-----
			//Initializing
			//-----
			function init(){
				canvas = document.getElementById('main');
				if ( ! canvas || ! canvas.getContext ) {
					return false;
				}
				ctx = canvas.getContext('2d');
				ctx.fillStyle = 'rgb(255, 255, 255)';
				
				loaded = 0;
				for(var i=0; i<1000; i++){
					layers[i] = new Layer();
					layers[i].setImage("movie/" + ("0000"+(i + 501)).slice(-5) + ".jpg",0,0,640,360,1);
					layers[i].img.onload = function(){
						loaded++;
						$("p").html("loaded image:"+loaded);
						if(loaded == 1000){
							starttimer();
							$("p").html("loaded image:"+loaded+"nya");
							starttimer2();
						}
					}
				}
			}
			firsttimer = 0;
			
			function starttimer(){
				if(firsttimer == 0){
					var timer;
					timer = setTimeout("starttimer()", 20000);
					firsttimer = 1;
				} else {
					for(var i=loaded; i<loaded + 500; i++){
						layers[i] = new Layer();
						layers[i].setImage("movie/" + ("0000"+(i + 501)).slice(-5) + ".jpg",0,0,640,360,1);
						layers[i].img.onload = function(){
							loaded++;
							$("p").html("loaded image:"+loaded);
							if(loaded%500 == 0){
								$("p").html("loaded image:"+loaded+"nya");
								if(loaded == 9000){
									
								} else {
									timer = setTimeout("starttimer()", 20000);
									firsttimer++;
								}
							}
						}
					}
				}
			}
			
			function starttimer2() {
				setInterval("onTimerEvent()", 1000/30);
			}
			
			var t2 = -1;
			//var t2 = 2000;
			function onTimerEvent(){
				
				
				if(t2>loaded){
					t2=0;
				}
				t2++;
				
				
				//-----
				//Animation test with hatune miku!
				//-----
				var top = t2 + 1;
				
				$("div").html(t2);
				
				//-----
				//Drawing layers
				//-----
				
				ctx.globalAlpha = layers[top].alpha;
				ctx.drawImage(
					layers[top].img,
					layers[top].x,
					layers[top].y,
					layers[top].width,
					layers[top].height
				);
			}
			
			//-----
			//Layer class
			//-----
			var Layer = function(){
				this.img = new Image();
				this.setImage = function(src, x, y, w, h, a){
					this.img.src = src;
					this.x = x;
					this.y = y;
					this.width = w;
					this.height = h;
					this.alpha = a;
					this.active = 1;
				}
				this.setPos = function(x, y){
					this.x = x;
					this.y = y;
				}
			}
			
			var layers = new Array(9000);
			
		//-->
		</script>
	</head>
	<body>
		<h1>Canvas</h1>
		<canvas id="main" width="640" height="480"></canvas>
		<p></p>
		<div></div>
	</body>
</html>

改築を繰り返したコードなのでいろいろ無駄はありますが、ひとまず9000枚の画像をロードして表示するプログラムです。
ちなみに実験時は、こちらの動画をお借りしました。
http://www.nicovideo.jp/watch/sm11299633