国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【譯文】Node.js垃圾回收機制-基礎

haobowd / 2705人閱讀

摘要:正好最近在學習的各種實現原理,在這里斗膽翻譯一篇垃圾回收機制原文鏈接。自動管理的機制中,通常都會包含垃圾回收機制。二垃圾回收機制的概念垃圾回收,是一種自動管理應用程序所占內存的機制,簡稱方便起見,本文均采用此簡寫。

最近關注了一個國外技術博客RisingStack里面有很多高質量,且對新手也很friendly的文章。正好最近在學習Node.js的各種實現原理,在這里斗膽翻譯一篇Node.js垃圾回收機制(原文鏈接)。

正文

在這篇文章中,你將會學習Node.js的垃圾回收(garbege collection)機制是如何工作的;即在你敲代碼的時候,后臺是怎么幫你清空內存里的垃圾的。

一、Node.js應用的內存管理

內存的適當分配,對于所有應用都至關重要。內存管理的任務,就是在程序請求內存的時候動態地為它們分配內存塊;并在程序不再需要內存的時候釋放掉。

應用級別的內存管理,有手動管理自動管理兩種模式。自動管理的機制中,通常都會包含垃圾回收機制

The following code snippet shows how memory can be allocated in C, using manual memory management:

下面的代碼片段展示了C語言中內存是如何分配的,這屬于手動管理:

#include 
#include 
#include 

int main() {

   char name[20];
   char *description;

   strcpy(name, "RisingStack");

   // memory allocation
   description = malloc( 30 * sizeof(char) );

   if( description == NULL ) {
      fprintf(stderr, "Error - unable to allocate required memory
");
   } else {
      strcpy( description, "Trace by RisingStack is an APM.");
   }

   printf("Company name = %s
", name );
   printf("Description: %s
", description );

   // release memory
   free(description);
}

在手動內存管理機制中,釋放無用內存的任務落在了程序猿身上。這樣可能會給應用帶來嚴重的問題:

內存泄露:可能某些占用的內存一直沒有被釋放。

當一個對象被刪除(過早釋放)的時候,可能會有指針不指向任何有效的對象,但仍然指向原來的內存。這種指針被稱為“懸掛指針”。這個時候如果再去使用這段內存,就會產生嚴重的安全問題。

但幸運的是,Node.js是自帶垃圾回收機制的,所以你不需要手動管理內存。

二、垃圾回收機制的概念

垃圾回收,是一種自動管理應用程序所占內存的機制,簡稱“GC”(方便起見,本文均采用此簡寫)。它的任務,就是回收無用對象(即垃圾)所占用的內存。它第一次出現,是在1959年的LISP語言中,由John McCarthy發明。

GC判斷一個對象為垃圾的標準是:是否還有其他對象引用它。

The way how the GC knows that objects are no longer in use is that no
other object has references to them.

如果沒有GC

下圖展示了沒有垃圾管理機制的時候,內存的情況。可以看到有的對象與其余的對象之間,沒有任何引用關系,但他們的內存也不會被回收。

有了GC之后

有了GC之后,沒有引用關系的對象占用的內存,都會被GC悄然回收。

使用GC的優勢

it prevents wild/dangling pointers bugs,
it won"t try to free up space that was already freed up,
it will protect you from some types of memory leaks.
Of course, using a garbage collector doesn"t solve all of your problems, and it’s not a silver bullet for memory management. Let"s take a look at things that you should keep in mind!

避免了懸掛指針的出現。

它不會嘗試去重復釋放并沒有被占用的內存。

它會防止某些類型的內存泄露。

當然了,GC并不能解決所有內存相關的問題,它不是解決內存管理問題的萬金油。有些使用GC的注意事項還是需要開發者牢記:

performance impact - in order to decide what can be freed up, the GC consumes computing power
unpredictable stalls - modern GC implementations try to avoid "stop-the-world" collections

對性能的影響:在判斷哪些內存要釋放的時候,GC會占用CPU資源。

不可預測的中斷:盡管現在的GC都會避免“停止一切”的情況發生,但是還是不可避免的會出現。

譯注:“停止一切”(stop-the-world)是指當垃圾收集沒有結束前,內存對于外部的請求是不會進行響應的,直到收集完畢應用才會繼續響應請求。

三、Node.js垃圾回收&內存管理實踐

學代碼就是要寫代碼,下面就用幾段代碼展示本節的主題。首先介紹幾個基本概念:

棧(Stack)

中存儲著本地變量、指向堆中對象的指針、定義應用程序控制流的指針。

在下面的例子中,變量a、b都會存儲在棧中。

function add (a, b) {  
  return a + b
}

add(4, 5)  
堆(Heap)

專門用于存儲“引用類型”的對象,例如字符串或對象。

下例中的Car對象就是保存在堆中的。

function Car (opts) {  
  this.name = opts.name
}

const LightningMcQueen = new Car({name: "Lightning McQueen"})  

執行之后,內存看上去會是這個樣子:

新建更多的Car對象的話,內存會變成這樣:

function Car (opts) {  
  this.name = opts.name
}

const LightningMcQueen = new Car({name: "Lightning McQueen"})  
const SallyCarrera = new Car({name: "Sally Carrera"})  
const Mater = new Car({name: "Mater"})  

如果這個時候執行垃圾回收,那么什么都不會發生,因為根對象(root)對每個對象都有引用。

那現在把上述例子再復雜化一點,給Car對象添加點“部件”。

function Engine (power) {  
  this.power = power
}

function Car (opts) {  
  this.name = opts.name
  this.engine = new Engine(opts.power)
}

let LightningMcQueen = new Car({name: "Lightning McQueen", power: 900})  
let SallyCarrera = new Car({name: "Sally Carrera", power: 500})  
let Mater = new Car({name: "Mater", power: 100})  

What would happen, if we no longer use Mater, but redefine it and assign some other value, like Mater = undefined?

現在,如果我們不想再使用Mater這個實例,把他賦一個別的值,比如Mater = undefined。這時會發生什么?

可以看到Mater失去了root對他的引用。那么,在下次垃圾回收執行的時候,它的內存就會被釋放。

好了,現在我們都理解了GC的基本原理和執行方式,來看看V8引擎中的GC是如何實現的吧!

垃圾回收方法

在我們之前的一篇文章中,我們介紹過Node.js的垃圾回收方法是如何工作的,我強烈建議閱讀此文章。

這篇文章的要點如下:

1. 新生代空間 & 老生代空間

堆中存在兩個“段”(segment),新生代空間(New Space)和老生代空間(Old Space)。新的內存分配都發生在新建空間中,它只有1-8MBs左右大,但垃圾回收卻很迅速和頻繁。這里存儲的對象稱為“新生代”(Young Generation)。

老生代空間中,存儲著那些新生代空間中未被回收,晉升至此的對象。它們被稱為“老生代”(Old Generation)。這里內存分配非常頻繁,但垃圾回收的成本卻很高,因此執行地不那么頻繁。

2. 新生代

通常只有20%左右的新生代會晉升為老生代。老生代空間只有在快被耗盡的時候,才會執行垃圾回收。V8引擎采用了兩種回收算法來實現:Scavenge 和 Mark-Sweep 。

Scavenge回收算法運算速度很快,用于新生代;慢一些的Mark-Sweep算法用于老生代。

四、現實案例The Meteor Case-Study

2013年,Meteor的作者們發布了一個他們遇到的內存泄露的例子。出問題的代碼段如下:

var theThing = null  
var replaceThing = function () {  
  var originalThing = theThing
  var unused = function () {
    if (originalThing)
      console.log("hi")
  }
  theThing = {
    longStr: new Array(1000000).join("*"),
    someMethod: function () {
      console.log(someMessage)
    }
  };
};
setInterval(replaceThing, 1000)  


Well, the typical way that closures are implemented is that every
function object has a link to a dictionary-style object representing
its lexical scope. If both functions defined inside replaceThing
actually used originalThing, it would be important that they both get
the same object, even if originalThing gets assigned to over and over,
so both functions share the same lexical environment. Now, Chrome"s V8
JavaScript engine is apparently smart enough to keep variables out of
the lexical environment if they aren"t used by any closures - from the
Meteor blog.

通常來說,實現閉包的方式為:每個函數對象都鏈接到一個字典式的對象,此對象表現其詞法作用域。如果replaceThing中兩個函數都使用了變量originalThing,那么即便originalThing被多次賦值,也必須保證這兩個函數得到的永遠是同一個對象,才能保證兩個函數共享一個詞法作用域。那么問題來了,Chrome的V8
JavaScript引擎只有在一個變量沒有被用在任何閉包中的時候,才會將其隔離在詞法環境之外。 - Meteor blog.

更多相關閱讀

Finding a memory leak in Node.js
JavaScript Garbage Collection Improvements - Orinoco
memorymanagement.org

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/91262.html

相關文章

  • 譯文-java垃圾回收機制

    摘要:原文出處垃圾回收機制標記清除算法介紹最主要的理論算法之一,在實踐過程中,為了真實情景需要,需要許多調整。因此不會僅僅標記清除,垃圾回收期間,內存整理進程同時在工作。不同內存區域的垃圾收集機制不辣么容易理解。 原文出處:java垃圾回收機制 標記清除算法介紹最主要的理論算法之一,在實踐過程中,為了真實情景需要,需要許多調整。舉一個簡單例子,我們檢查JVM需要做的各種事情,以便我們安全地去...

    Warren 評論0 收藏0
  • 譯文-垃圾回收器是什么

    摘要:垃圾回收器追蹤所有正在使用的對象,將無用對象標記為垃圾。自動化指針內存回收自動化的最好方式之一是使用鉤子函數。它們可能因為多種原因發生,但是這種垃圾回收器是最主流的一種。 原文出處:What Is Garbage Collection? 一眼就應該從名稱看出垃圾回收機制的含義-查找垃圾,然后丟棄。事實正好相反。垃圾回收器追蹤所有正在使用的對象,將無用對象標記為垃圾。請留意,我們開始研究...

    alanoddsoff 評論0 收藏0
  • 簡述JavaScript的垃圾回收機制

    摘要:關鍵是釋放內存這一步,各種語言都有自己的垃圾回收簡稱機制。用的是這種,在字末位進行標識,為指針。對于而言,最初的垃圾回收機制,是基于引用計次來做的。老生代的垃圾回收,分兩個階段標記清理有和這兩種方式。 不管是高級語言,還是低級語言。內存的管理都是: 分配內存 使用內存(讀或寫) 釋放內存 前兩步,大家都沒有太大異議。關鍵是釋放內存這一步,各種語言都有自己的垃圾回收(garbage ...

    wenshi11019 評論0 收藏0
  • javascript 垃圾回收算法

    摘要:它將堆內存一分為二每一部分空間稱為。以的垃圾回收堆內存為例做一次小的垃圾回收需要毫秒以上做一次非增量式的垃圾回收甚至要秒以上。這是垃圾回收中引起線程暫停執行的時間在這樣的時間花銷下應用的性能和響應能力都會直線下降。 我們通常理解的 javascript 垃圾回收機制都停留在表面,會釋放不被引用變量內存,最近在讀《深入淺出node.js》的書,詳細了解了下 v8 垃圾回收的算法,記錄了一...

    simon_chen 評論0 收藏0
  • Node - 內存管理和垃圾回收

    摘要:的內存限制和垃圾回收機制內存限制內存限制一般的后端語言開發中,在基本的內存使用是沒有限制的。的內存分代目前沒有一種垃圾自動回收算法適用于所有場景,所以的內部采用的其實是兩種垃圾回收算法。 前言 從前端思維轉變到后端, 有一個很重要的點就是內存管理。以前寫前端因為只是在瀏覽器上運行, 所以對于內存管理一般不怎么需要上心, 但是在服務器端, 則需要斤斤計較內存。 V8的內存限制和垃圾回收機...

    joyqi 評論0 收藏0

發表評論

0條評論

haobowd

|高級講師

TA的文章

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