成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯]編寫高性能對垃圾收集友好的代碼

cfanr / 3156人閱讀

摘要:創(chuàng)建多個對象同樣也會影響垃圾回收。譯注這里清除的是變量中存放的數(shù)據(jù)避免創(chuàng)建對象當(dāng)然,降低垃圾回收最簡單的方式是不要去創(chuàng)建對象。并不存在無痛地有效刪除數(shù)組中某個對象的方法。

部分翻譯自原文地址

若你想讓你的游戲有60楨/秒的體驗,你必須要做的就是在16浩渺內(nèi)完成所有事:子彈運動,創(chuàng)建實體,控制碰撞,軌跡,變換場景,控制輸入,播放音效。主流的游戲循環(huán)中,你需要做到盡可能高效。即便在30楨/秒的體驗中,你也只有32毫秒去完成這一切。特別是當(dāng)你想要讓游戲更加豐滿時,速度與效率會顯得尤為重要。

垃圾回收究竟是什么?為何要關(guān)注垃圾回收?

如果你開發(fā)的游戲在同一時間內(nèi)發(fā)生了許多事,例如每秒發(fā)射5次導(dǎo)彈的武器(一把有著極高射速的非凡武器)。你很快就會發(fā)現(xiàn)原型構(gòu)建及其后的垃圾回收將嚴(yán)重拖累性能。

當(dāng)你的項目變得越來越復(fù)雜,在構(gòu)建新事物時,你將會感受到明顯的延遲,特別是當(dāng)你設(shè)置復(fù)雜場景與音效時(即便你已經(jīng)緩存了靜態(tài)資源)。創(chuàng)建多個對象同樣也會影響垃圾回收。

像其他解釋型語言一樣JavaScript把你從內(nèi)存管理中解放出來。你可以隨意創(chuàng)建對象而不用去考慮追蹤的問題。瀏覽器(實際上是運行在瀏覽器環(huán)境中的js虛擬器)將會周期性運行并清除你不用的代碼。這部分系統(tǒng)就是垃圾回收(garbage collector)簡稱GC,你可以把它想象為終極女傭。

有賴于瀏覽器,你使用的大量的對象可以在垃圾回收機制下在10到2000毫秒內(nèi)被清除。該機制花費的時間取決于,究竟有多少代碼需要檢查,有多少對象需要清除。如果你在寫一個有許多獨立運行的對象的游戲,例如作戰(zhàn)類游戲。最好的情況是可察覺的卡頓,而最壞的情況則是大量的卡頓毀掉了體驗。

有好的垃圾回收代碼

大多數(shù)情況有賴于垃圾回收機制,我們可以很輕易編寫代碼。唯一需要注意的就是不要應(yīng)用那些你已經(jīng)不需要使用的對象。例如下面的案例:

function test()
{
   var myString = "a string";
}

test();

在函數(shù)test執(zhí)行之后,變量myString 將會被標(biāo)記為閑置的等待釋放/刪除。因為函數(shù)創(chuàng)建了一個可聲明變量的作用域。在作用域中,瀏覽器會為開辟空間存放變量myString直到函數(shù)不再被使用,作用域中的一切都將被回收。在其后的某個時刻(由瀏覽器自行計算),GC將會執(zhí)行,變量myString 會“真地”被移除內(nèi)存得到釋放。

當(dāng)然如果還有引用,GC將不會回收變量,如:

var another = null;

function test()
{
    var str = "A string I am";
    another = str;
}
    
test();     

在上例中,全局作用域中的另一個變量在函數(shù)內(nèi)引用了str,因此垃圾回收器將不會回收str。

再看看別的例子,當(dāng)你不適用var關(guān)鍵字時,js會將其理解為一個全局變量:

// var b = null; // 在外部聲明

function test()
{
    var str = "A string I am";
    b = str; // 沒有var 會被理解為全集變量
}
    
test();
如何真正地刪除變量?

那么問題來了,如何真實地了解到變量是否被刪除,即被垃圾回收器清理了?

var s = { data: "test" };
delete s.data;

首先,JavaScript提供了delete關(guān)鍵字,所以可以用它來實現(xiàn)?不幸的是,不能。delete是用來清除對象屬性的。顯然這是一個間接清除對對象/變量清除引用的方式,但這并沒有直接刪除變量。當(dāng)你想要把一個對象的屬性變成undefined而非null時,該方法還是挺有用的:

var s = { data: "test" };
delete s.data;

s.data現(xiàn)在變?yōu)榱?b>undefined(同時也被垃圾回收器標(biāo)記為“去除”)

當(dāng)你使用同樣的方式用delete去刪除一個變量時將會失?。?/p>

var m = "test";
delete m; // 默認(rèn)返回 false (不允許操作)
m === "test"; // true - oops, 依舊是那個值

delete很好用,但對于一個變量(這里指基本類型)則會失效。因此引用并不會被清除,內(nèi)存也不會被垃圾回收器回收。使用delete將返回false來表示這個變量不會被刪除。

刪除變量真確的方式是:把變量設(shè)為null,之后垃圾回收器就會去做他該做的事。

var m = "test";
m = null;
m === "test"; // false

該方法對屬性與對象同樣適用:

var s = { data: "test" };
s.data = null;  // not required
s = null;   // 該操作同時也會清除s.data

其后數(shù)據(jù)將自動清除,因為沒有變量引用它了。
(譯注:這里清除的是變量中存放的數(shù)據(jù))

避免創(chuàng)建對象

當(dāng)然,降低垃圾回收最簡單的方式是不要去創(chuàng)建對象。最直接的方式就是使用new關(guān)鍵字。

var newObject = new MyObject();

但是還有一些更簡潔的方法:

var a = [];   // 創(chuàng)建一個數(shù)組
var t = { };  // 創(chuàng)建一個對象

需要記住的是function也會被當(dāng)作對象處理:

function getCompare()
{
    return function(a, b) { return a < b; }
}

這段代碼在每次調(diào)用時都會生成一個新的(函數(shù))對象。在JavaScript中由于函數(shù)是一個對象,所以垃圾回收器也能用同樣的方式處理。

另一種產(chǎn)生對象的方式是使用函數(shù):

function getResult(}
{
    return { result: true, value: "test" }; //調(diào)用時創(chuàng)建新的對象
}

最后,有一個藏得很深的方式:

var b = a.slice(1); // 創(chuàng)建一個新的完全復(fù)制的數(shù)組

Array.slice方法在每次調(diào)用時會創(chuàng)建一個新的對象/數(shù)組。并不存在無痛地有效刪除數(shù)組中某個對象的方法。誠然現(xiàn)在瀏覽器在這方面做了很多優(yōu)化,但頻繁進行這樣的操作對性能仍是一種挑戰(zhàn)。(在Playcraft引擎采用雙向鏈表作為替代,詳見gamecore.js)

可控的垃圾回收

即便你降低了你創(chuàng)建對象的數(shù)量,你依舊在消耗內(nèi)存。你可以使用一個相當(dāng)簡單的工具來了追蹤你消耗的內(nèi)存即因而帶來的垃圾回收工作消耗的內(nèi)存。

Chrome提供了一個觀測JavaScript堆(分配給JavaScript對象的內(nèi)存)狀態(tài)的方式,你需要在命令行輸入一下代碼來保證其能夠運行:

chrome --enable-memory-info

如果你想要永久的使用這個工具,你可以這樣做:

do shell script 
  ""/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"     
      --enable-memory-info"

保存這段腳本并將其作為你新的Chrome launcher。

一旦你啟動了Chrome 的內(nèi)存分析,你可以訪問如下兩個屬性:

window.performance.memory.totalJSHeapSize;  // 當(dāng)前使用的堆內(nèi)存
window.performance.memory.usedJSHeapSize; // 全部的堆內(nèi)存

這兩個值表示當(dāng)前有多少內(nèi)存被分配給JavaScript,其中有多少被所有的變量/對象使用。如果你規(guī)律地輸出被使用的堆,你可以了解到你游戲的內(nèi)存使用情況。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86601.html

相關(guān)文章

  • JavaScript 工作原理之三-內(nèi)存管理及如何處理 4 類常見內(nèi)存泄漏問題()

    摘要:這是因為我們訪問了數(shù)組中不存在的數(shù)組元素它超過了最后一個實際分配到內(nèi)存的數(shù)組元素字節(jié),并且有可能會讀取或者覆寫的位。包含個元素的新數(shù)組由和數(shù)組元素所組成中的內(nèi)存使用中使用分配的內(nèi)存主要指的是內(nèi)存讀寫。 原文請查閱這里,本文有進行刪減,文后增了些經(jīng)驗總結(jié)。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第三章。 我們將會討論日常使用中另一個被開發(fā)...

    weknow619 評論0 收藏0
  • 】PHP:40+開發(fā)工具推薦

    摘要:今天,就為開發(fā)者介紹個方便的工具。對開發(fā)者來說,是一個非常有用的工具,它提供了超過個有用的函數(shù)。該工具檢查輸入源代碼和報告任何違反給定的標(biāo)準(zhǔn)??蚣苁且粋€開發(fā)的工具。它側(cè)重于安全性和性能,絕對是最安全的開發(fā)框架之一。 PHP是為Web開發(fā)設(shè)計的服務(wù)器腳本語言,但也是一種通用的編程語言。超過2.4億個索引域使用PHP,包括很多重要的網(wǎng)站,例如Facebook、Digg和WordPress。...

    dreambei 評論0 收藏0
  • 】深入理解G1GC日志(一)

    摘要:表示允許垃圾收集線程處理本次垃圾收集開始前沒有處理好的日志緩沖區(qū),這可以確保當(dāng)前分區(qū)的是最新的。垃圾收集線程在完成其他任務(wù)的時間展示每個垃圾收集線程的最小最大平均差值和總共時間。 本文翻譯自:https://www.redhat.com/en/blog/collecting-and-reading-g1-garbage-collector-logs-part-2?source=auth...

    spacewander 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<