2011-09-20 37 views
16

我正在研究HTML 5遊戲,它已經在線,但它目前很小,一切都還好。使用JavaScript卸載HTML中的資源

事情是,隨着它的增長,它將會加載許多許多圖像,音樂,音效等等。在玩遊戲15分鐘後,至少有100種不同的資源可能已經加載。由於它是一個HTML5應用程序,它在遊戲過程中從不刷新頁面,因此它們都在後臺堆疊。

我注意到我加載的每個資源 - 至少在WebKit上,使用Web Inspector - 一旦我將<img><link>移除到CSS和其他位置,我仍然保留在那裏。我猜它仍然在記憶中,只是沒有被使用,對吧?

這最終會消耗大量內存,導致性能下降,尤其是iOS和Android手機(我稍微注意到當前版本)的性能下降,其資源比桌面計算機更爲有限。

我的問題是:是否可以通過JavaScript完全卸載資源,釋放RAM中的空間?而不必刷新整個頁面來「清除」。

最糟糕的情景:使用框架幫助,通過刪除一個框架,釋放這些框架的資源?

謝謝!

+3

你可以嘗試做的一件事是設置相應的資源句柄爲'null'。只要資源沒有從任何地方引用,它使用的內存就應該被javascript引擎垃圾收集。 –

+0

我會試試!謝謝!你介意與我分享一個關於如何訪問瀏覽器加載的資源的例子的鏈接嗎?我很難在Google上找到它=/ – ArtPulse

+0

在Firefox和Chrome中,垃圾收集器似乎在切換到另一個選項卡時運行。我不確定這對你有多大用處,但如果用戶不是連續玩遊戲,那麼應該很好地相信垃圾收集器。 – pimvdb

回答

3

您的描述意味着您完全刪除了對資源的所有引用。那麼你所看到的行爲就是垃圾收集器沒有被調用來清理空間,這在JavaScript實現中很常見,直到「必要」。設置爲null或致電delete通常不會更好。

作爲一種常見情況,您通常可以在場景加載/卸載過程中調用CollectGarbage()來強制收集過程。這通常是數據加載遊戲「階段」時的最佳解決方案,因爲這個時間不是時間關鍵。你通常不希望收集器在遊戲過程中調用,除非它不是一個非常實時的遊戲。

如果您想爲常用遊戲控件保留一定的資源,框架通常是一個困難的解決方案。你需要考慮你是刷新整個資源還是隻是某些資源。

+0

是的!這就是爲什麼我想避免使用幀。我不想重複我的資源,它必須進行優化。 - 那麼你是通過調用這個方法來說的嗎,JS會從內存中清除我在那個時刻不使用的所有東西? (如加載的圖像,但不插入HTML中的任何地方?) – ArtPulse

+0

@ArtPulse:它應該強制它的操作,儘管我已經看到一些較早的實現將它解釋爲一個提示。所以所有未被引用的對象都將被刪除。通常最好先開始繼續添加資源,並在考慮使用GC後臺操作是否不夠充分,但遊戲開發人員更頻繁地使用它,因爲他們知道GC收集可能發生的位置,而不會干擾遊戲。 – ex0du5

+0

好吧!但是,它只刪除未使用的JS變量嗎?如果由HTML上的標籤下載的圖像不再被任何標籤使用,那麼它會不會被使用? GC會刪除該資源嗎? – ArtPulse

1

你說最壞的情況:會使用框架幫助,通過刪除幀,以釋放這些幀的資源

這是很好的使用框架。是的,它可以通過刪除幀來釋放資源。

+0

它確實有用嗎?至少那是一個故障安全。例如,我可以在一個框架中加載一場完整的戰鬥,一旦完成,就殺了它。我會試着看看它是如何響應的。 – ArtPulse

+0

我不鼓勵使用框架。他們實際上放棄了HTML5中的''標籤http://www.w3.org/TR/html5-diff/ – Alex

+0

我不喜歡框架。這就是爲什麼我不想使用它們的原因xD – ArtPulse

3

您所能做的就是依靠JavaScript內置的垃圾回收機制。

只要沒有提及您的圖像,就會啓動此功能。

因此,假如你有一個參考指針每幅圖像,如果你使用:

img.destroy() 

img.parentNode.removeChild(img) 

值得一試:http://www.ibm.com/developerworks/web/library/wa-memleak/

另外:Need help using this function to destroy an item on canvas using javascript

編輯

下面是一些代碼,允許您將圖像加載到var。

<script language = "JavaScript"> 


var heavyImage = new Image(); 
heavyImage.src = "heavyimagefile.jpg"; 

...... 

heavyImage = null; // removes reference and frees up memory 

</script> 

這是更好地從使用JQuery .load(),原因是其爲您提供了圖像引用更多的控制權,他們會從內存中,如果引用是丟失被刪除(null

措施:http://www.techrepublic.com/article/preloading-and-the-javascript-image-object/5214317

希望它有幫助!

+0

每個部分都通過jQuery.load()加載,其中插入了HTML和標籤以及其他內容。實際上,這就是一切正常的方式。通過刪除它們,它們仍然可以在Web Inspector中看到。你的意思是我應該加載JavaScript的每個圖像以便能夠從JavaScript中「卸載」它們嗎? – ArtPulse

+0

聽起來不錯。儘管通過這種媒介實現遊戲中的一切將需要更長的時間,並且改變了已經完成的許多事情。但是請記住這是一種可能性,謝謝=) – ArtPulse

+0

不要忘記你可以使用'Array()'來保存多個圖像(如果有幫助的話) – Alex

0

好的,所以我通過將3個不同的HTML加載到<文章>標記中進行了測試。每個HTML都有許多巨大的圖像。每個「頁面」大約有15幅巨大的圖像。

所以我用jQuery.load()函數在標籤中插入每一個。還有一個額外的HTML,只有一個< h1>,以查看當沒有圖像的頁面正在替換上一頁時發生了什麼。

嗯,當你開始滾動時,RAM會變得更大,並且在通過一個特別大的圖像(尺寸和大小,而不僅僅是大小)很大時會出現。但是一旦你離開後面,更輕的圖像出現在屏幕上,內存消耗實際上就會下降。而且,當我用頁面的內容替換JS時,內存佔用太多時,內存消耗就會減少。虛擬內存一直很高,很少出現故障。

所以我猜瀏覽器相當聰明地處理資源。如果你長時間離開它,它似乎不會卸載它們,但只要你開始加載其他頁面或滾動,它就開始加載/釋放。

我想我畢竟沒什麼好擔心的......

謝謝大家! =)

3

有2層更好的方法來加載圖像,除了正常的<img>標籤,其中谷歌精闢論述這裏:

http://www.youtube.com/watch?v=7pCh62wr6m0&list=UU_x5XG1OV2P6uZZ5FSM9Ttw&index=74

  1. 通過HTML5 <canvas>加載在圖像被方式方法更快。我真的會觀看那些視頻,並以更快的速度實施這些方法。我會想象垃圾收集與畫布會更好地發揮作用,因爲它正在脫離DOM。

  2. 嵌入式數據URL,圖像標籤的src屬性是圖像的實際二進制數據(是的,它是一個巨大的字符串)。它是這樣開始的:src="data:image/jpeg;base64,/9j/MASSIVE-STRING ... "使用這個之後,你當然會想用一種方法去除這個節點,正如其他答案中所討論的那樣。 (我不知道如何生成這個base64字符串,嘗試谷歌或視頻)

+1

聽起來不錯!一定會牢記這一點。謝謝德文! – ArtPulse

+0

呃我們都應該把自己的時間自願送給StackOverflow的其他人 –