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

資訊專欄INFORMATION COLUMN

qcon行node總結(jié)

sydMobile / 2351人閱讀

摘要:進(jìn)程運(yùn)行中沒被回收肯定屬于內(nèi)存泄漏關(guān)于這個(gè)定義引起討論是在進(jìn)程退出或崩潰后的情況。關(guān)于異步處理問題不適合處理復(fù)雜的狀態(tài)機(jī)解決方案是使用隊(duì)列結(jié)構(gòu)進(jìn)行可控的異步并發(fā)。

front to back

業(yè)務(wù)上 : front 面向展示 交互 ; back 功能 服務(wù) 數(shù)據(jù)一致性等等

環(huán)境 : front browser webview 單機(jī); back 集群 高并發(fā)

思想差異 : front 快速開發(fā) 快速渲染 視覺效果 等等 ; back 服務(wù)穩(wěn)定,性能,內(nèi)存泄漏等等

V8 內(nèi)存的簡(jiǎn)介

首先通過memoryUsage可以查看node進(jìn)程的使用情況,具體介紹如下

process.memoryUsage();   查看node進(jìn)程內(nèi)存使用情況  單位是字節(jié)
{ rss: 20725760,  (resident set size)進(jìn)程的常駐內(nèi)存   
  heapTotal: 7376896,   已申請(qǐng)到的堆內(nèi)存
  heapUsed: 3881280,  當(dāng)前使用的堆內(nèi)存
  external: 8772  ,  c++的內(nèi)存使用,受v8管理
  }
  

針對(duì)上面api使用寫了個(gè)相關(guān)例子

let  showMem=function () {
    var mem=process.memoryUsage();
    var format=function (bytes) {
        return (bytes/1024/1024).toFixed(2)+"MB";
    }
    console.log("Process :heapTotal "+format(mem.heapTotal)+" heapUsed "+ format(mem.heapUsed)+" rss "+format(mem.rss));
    console.log("------------------------------------")
}
var useMem=function () {
    var size=200*1024*1024;    //每次構(gòu)建200MB對(duì)象
    var buffer=new Buffer(size);
    for(var i=0;i

heapTotal和heapUsed變化極小,唯一變化rss值,且該值遠(yuǎn)超V8內(nèi)存分配限制(說明:V8的內(nèi)存限制:64位系統(tǒng)約為1.4GB、32位系統(tǒng)約為0.7GB (這個(gè)規(guī)定是node源碼 中限制的),具體測(cè)試可以將上述實(shí)例中buffer改成array即可)

說明:node 內(nèi)存由通過v8進(jìn)行分配的部分(新生到和老生代)(只有這部分才會(huì)受v8垃圾回收的限制)和node進(jìn)行自行分配的部分(例如buffer)

額外補(bǔ)充

--max-old-space-size 命令就是設(shè)置老生代內(nèi)存空間的最大值

--max-new-space-size 命令則可以設(shè)置新生代內(nèi)存空間的大小

這兩個(gè)參數(shù)只能在node啟動(dòng)時(shí)進(jìn)行設(shè)置

下面從gc層面談?wù)撓聉8內(nèi)存,這個(gè)可以說很多,我的云筆記中關(guān)于java和js的內(nèi)存使用,分配,gc等整理了好幾個(gè)系列,下面我用自己的話簡(jiǎn)單總結(jié)下。

關(guān)于內(nèi)存分區(qū)有以下兩個(gè)大類:

new space(特征:對(duì)象存活時(shí)間短) 又分為from和to兩個(gè)區(qū)域,采用復(fù)制算法,空間換時(shí)間。如果存活多次,轉(zhuǎn)移到老生代中。

老生代中(對(duì)象存活時(shí)間長(zhǎng)),采用mark-sweep(標(biāo)記清除)和mark-compact(標(biāo)記整理),缺點(diǎn)容易形成內(nèi)存碎片,導(dǎo)致無法分配大對(duì)象。v8主要使用mark-sweep,在內(nèi)存空間不夠時(shí),才使用標(biāo)記整理。老生代又可以細(xì)分Old Space(新生代中g(shù)c活過2次晉升到這個(gè)空間)、Large Object Space(大對(duì)象,一般指超過1MB,初始時(shí)直接分配到此),Map Space(“隱藏類”的指針,便于快速訪問對(duì)象成員)、Code Space(機(jī)器碼,存儲(chǔ)在可執(zhí)行內(nèi)存中)

關(guān)于gc,總的來說在js中不同對(duì)象存活時(shí)間不同,沒有一種算法適應(yīng)所有場(chǎng)景,內(nèi)存垃圾進(jìn)行分代,針對(duì)不同分代使用相應(yīng)高效算法,有些gc算法和java是一樣的,復(fù)制(空間換時(shí)間,new Space),標(biāo)記清除和標(biāo)記整理(old space)等等。

補(bǔ)充存活標(biāo)記依據(jù)

全局變量或者有由全局變量出發(fā),可以訪問到的對(duì)象

正在執(zhí)行的函數(shù)中的局部對(duì)象,包括這些局部對(duì)象可以訪問到的對(duì)象。

閉包中引用的對(duì)象

關(guān)于內(nèi)存,偏底層語言(例如c)和js以及java不一樣

#c代碼
 #include 
 void init()
{
int arr[5]={};
for(int i=0;i<5;i++){
    arr[i]=i;
}
}
void test(){
    int arr[5];
    for(int i =0;i<5;i++){
        printf("%d
",arr[i]);
    }
}
int main(int argc,char const *argv[]){
    init();
    test();
    return 0;
}
//  0 1 2 3 4
# java代碼
public class Test {

    public static  void  main(String[] args){
            init();
            test();
    }
    public static void init(){
        int[] arr=new int[]{0,1,2,3,4};
//        for(int i=0;i<5;i++){
//            System.out.println(arr[i]);
//        }
    }
    public static  void test(){
        int[] arr=new int[5];
        for(int i=0;i<5;i++){
            System.out.println(arr[i]);
        }
    }

}
//  0 0 0  0 0

上述例子說明c語言堆棧執(zhí)行過程中,函數(shù)執(zhí)行完堆棧釋放,程序員如果不關(guān)注釋放過程,出現(xiàn)一些問題 ,
而js和java就不會(huì),因?yàn)閮?nèi)存自動(dòng)分配,垃圾自動(dòng)回收,不用考慮臟數(shù)據(jù)擦除。

內(nèi)存泄漏

首先什么是內(nèi)存泄漏?

對(duì)象不再被應(yīng)用程序使用,但是垃圾回收器卻不能移除它們,因?yàn)樗鼈冋诒灰谩?/p>

node進(jìn)程運(yùn)行中g(shù)arbage沒被回收肯定屬于內(nèi)存泄漏,關(guān)于這個(gè)定義引起討論是在node進(jìn)程退出或崩潰后的情況。我的理解是如果有部分內(nèi)存比如共享內(nèi)存(用于進(jìn)程間通信),如果沒被釋放,這依然屬于內(nèi)存泄漏,內(nèi)存泄漏不僅僅只進(jìn)程層面。

內(nèi)存泄漏原因有好幾種,ppt有的,我不在列舉,我在分享過程中有同學(xué)提出個(gè)疑問,關(guān)于exports使用中為什么會(huì)導(dǎo)致泄漏,印象比較深刻,可能當(dāng)時(shí)講的不清楚,下面寫個(gè)具體例子詳細(xì)闡述下。

//A.js
var leakAry=[];
exports.leak=function(){
    leakAry.push("leak "+" gcy "+new Date());
}
//B.js
var obj=require("./a");
for(var i=0;i<10;i++){
    obj.leak();
}

在node當(dāng)中,為了加速module訪問,所有module都會(huì)被編譯緩存,上述代碼導(dǎo)致泄漏的原因就是模塊上,被緩存局部變量重復(fù)訪問,因?yàn)闆]初始化,導(dǎo)致內(nèi)存占用不斷增大。

其次平時(shí)如何定位內(nèi)存泄漏具體問題。

var http=require("http");
 var heapdum=require("heapdump");
var leakArray=[];
var leak=function () {
    for(var i=0;i<100000;i++){
        leakArray.push("leak "+Math.random());
    }
   
};
var i=0;
http.createServer(function (req,res) {
    leak(); //泄漏觸發(fā)位置
    i++;
    res.writeHead(200,{"Content-Type":"text/plain"});
    res.end("hello world gcy"+i);
}).listen(1337);
console.log(process.pid);
console.log("server start  gcy");

-------------------------------------------------------------
for ((i=1;i<=10000;i++));
 do   curl -v --header "Connection: keep-alive" "http://127.0.0.1:1337/"
  done
  批量100和10000個(gè)請(qǐng)求,記錄heap dump鏡像,通過對(duì)比視圖查看變化比較大地方,通過分析定位具體泄漏位置,展示效果如下圖

可以看到有三處對(duì)象明顯增長(zhǎng)的地方,string、concatenated string以及 array 對(duì)象增長(zhǎng)。點(diǎn)擊查看一下對(duì)象的引用情況,可以發(fā)現(xiàn)原因是leak執(zhí)行,leakArray沒有初始化,導(dǎo)致其里面字符串沒有被清除,從而導(dǎo)致內(nèi)存泄漏。

關(guān)于異步處理

問題:不適合處理復(fù)雜的狀態(tài)機(jī)

解決方案:是使用隊(duì)列結(jié)構(gòu)進(jìn)行可控的異步并發(fā)。

關(guān)于這一點(diǎn)理解分享中上有人提出可異議,
我的理解是比如邏輯中有大量的promise待處理,一旦此邏輯比較多,我們沒法掌控,宏觀上沒法知曉具體執(zhí)行情況,但是通過隊(duì)列,在高并發(fā)請(qǐng)求下,大量的狀態(tài)機(jī)promise通過隊(duì)列
的管理,我們可以做到可控,哪些被消費(fèi)了,狀態(tài)機(jī)所處某個(gè)過程的比例都可以統(tǒng)計(jì),一旦有這些統(tǒng)計(jì)信息,我們就可以進(jìn)行相應(yīng)的處理。求證。

弱計(jì)算

什么是 IO 密集型? 控制器busy

什么是 CPU 密集型? 運(yùn)算器busy

關(guān)于弱計(jì)算的分析可以用node生成profile文件,然后通過chrome進(jìn)行分析或者webstrome自帶的v8 profiling進(jìn)行分析,可以得到一系列函數(shù)執(zhí)行時(shí)間統(tǒng)計(jì)和調(diào)用堆棧過程時(shí)間消耗統(tǒng)計(jì),依據(jù)這些信息,我們?cè)谧鱿鄳?yīng)的優(yōu)化。圖中顯示的是例子test2的結(jié)果。

部署 child_process
//普通情況,只是作為用法示例
var fork=require("child_process").fork;
var cpus=require("os").cpus();
for(var i=0;i
總結(jié)

child_process 模塊給node提供了一下幾個(gè)方法創(chuàng)建子進(jìn)程
1: spwan(); 啟動(dòng)一個(gè)子進(jìn)程執(zhí)行命令
2: exec() 啟動(dòng)一個(gè)子進(jìn)程執(zhí)行命令,與spwan不同的是,他有一個(gè)回調(diào)函數(shù)獲知子進(jìn)程狀況
3: fork() 與spwan類似 不同地方在于 在創(chuàng)建子進(jìn)程的時(shí)候只需指定 需要執(zhí)行的JavaScript文件即可

上面方法很少用了,node當(dāng)中有cluster模塊,簡(jiǎn)單的幾個(gè)方法就可以創(chuàng)建集群,其本質(zhì)基于上面的封裝,底層實(shí)現(xiàn)原理基于句柄共享。

var index=require("./app");
if (cluster.isMaster)
    for (var i = 0, n = os.cpus().length; i < n; i += 1)
        cluster.fork();
else
    index.app();
-------------------------------------------
//app.js
function app() {
    var server = http.createServer(function(req, res) {
        res.writeHead(200);
        res.end("hello world gcy
");
        console.log(cluster.worker.id);
    });
    server.listen(8088);
}
exports.app=app;

cluster使用中有三個(gè)問題
1、round-robin是當(dāng)前cluster的默認(rèn)負(fù)載均衡處理模式(除了windows平臺(tái)),自行設(shè)定負(fù)載算法
可以在cluster加載之后未調(diào)用其它c(diǎn)luster函數(shù)之前執(zhí)行:cluster.schedulingPolicy = cluster.SCHED_NONE。

2、進(jìn)程監(jiān)控問題
master進(jìn)程不會(huì)自動(dòng)管理worker進(jìn)程的生死,如果worker被外界殺掉了,不會(huì)自動(dòng)重啟,
只會(huì)給master進(jìn)程發(fā)送‘exit’消息,開發(fā)者需要自己做好管理。

3、數(shù)據(jù)共享問題
各個(gè)worker進(jìn)程之間是獨(dú)立的,為了讓多個(gè)worker進(jìn)程共享數(shù)據(jù)(譬如用戶session),
一般的做法是在Node.js之外使用memcached或者redis。

cluster適用于在單臺(tái)機(jī)器上,如果應(yīng)用的流量巨大,多機(jī)器是必然的。這時(shí),反向代理就派上用場(chǎng)了,我們可以用node來寫反向代理的服務(wù)(比如用 http-proxy )
,好處是可以保持工程師技術(shù)棧的統(tǒng)一,不過生產(chǎn)環(huán)境,我們用的更多的還是nginx,部分重要配置如下。

nginx做集群

upstream gcy.com{
        server 127.0.0.1:3000 weight=1;
        server 127.0.0.1:3001 weight=2;
        server 127.0.0.1:3002 weight=6;

    }
維護(hù)

維護(hù)主要做好以下三點(diǎn)

日志

異常處理

第三方依賴管理。

異常處理解釋下,有人提出疑問:異常沒有被捕獲一路冒泡 ,會(huì)觸發(fā)uncaughtException 事件,
如果異常出現(xiàn)之后,沒有進(jìn)行正確的恢復(fù)操作可能導(dǎo)致內(nèi)存泄漏,清理已使用的資源
(文件描述符(清除文件的占用)、句柄(Master傳給work的標(biāo)識(shí))等) 然后 process.exit。

總結(jié)

qcon現(xiàn)場(chǎng)聽一次,自己分享一次,總結(jié)一次,感覺收貨蠻大的,有些地方自己加深了理解,分享中front to back開頭部分,原先8頁太多,本應(yīng)一筆帶過,講的時(shí)候廢話太多,原本我只想闡述其中幾個(gè)關(guān)鍵名詞。
分享本身是一個(gè)學(xué)習(xí),開拓眼界的的過程,切身體會(huì),還是需要自己實(shí)踐,寫具體case。
上述基本上是我講的過程記錄,做個(gè)總結(jié),以便回顧。
演示部分鏈接, demo

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/82870.html

相關(guān)文章

  • FEDAY2016之旅

    摘要:前戲補(bǔ)上參會(huì)的完整記錄,這個(gè)問題從一開始我就是準(zhǔn)備自問自答的,希望可以通過這種形式把大會(huì)的干貨分享給更多人。 showImg(http://7xqy7v.com1.z0.glb.clouddn.com/colorful/blog/feday2.png); 前戲 2016/3/21 補(bǔ)上參會(huì)的完整記錄,這個(gè)問題從一開始我就是準(zhǔn)備自問自答的,希望可以通過這種形式把大會(huì)的干貨分享給更多人。 ...

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

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

0條評(píng)論

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