亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

cfanr / 3220人閱讀

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

部分翻譯自原文地址

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

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

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

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

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

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

有好的垃圾回收代碼

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

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

test();

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

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

var another = null;

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

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

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

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

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

那么問(wèn)題來(lái)了,如何真實(shí)地了解到變量是否被刪除,即被垃圾回收器清理了?

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

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

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

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

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

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

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

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

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

該方法對(duì)屬性與對(duì)象同樣適用:

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

其后數(shù)據(jù)將自動(dòng)清除,因?yàn)闆](méi)有變量引用它了。
(譯注:這里清除的是變量中存放的數(shù)據(jù))

避免創(chuàng)建對(duì)象

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

var newObject = new MyObject();

但是還有一些更簡(jiǎn)潔的方法:

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

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

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

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

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

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

最后,有一個(gè)藏得很深的方式:

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

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

可控的垃圾回收

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

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

chrome --enable-memory-info

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

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

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

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

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/86601.html

相關(guān)文章

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

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

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

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

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

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

    spacewander 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<