fork守护程序中的v8内存泄漏

时间:2017-12-18 18:06:31

标签: c++ memory-leaks fork v8

  • v8版本为6.3.292
  • Centos6 / 7

我有这种架构(我的守护进程有异步工作模型):

  1. 我使用一个线程初始化v8平台,该线程可以生成3-4个孩子。
  2. 我为每个孩子和主人分离。
  3. Master没有内存泄漏,但孩子们没有。
  4. 在某些时候,孩子会使用99%的CPU,什么都不做。
  5. 即使我尝试为每个主人和孩子初始化平台,我也有同样的问题

    在v8的3.14版中,这样的模型没有内存泄漏。

    v8::Isolate* isolate;
    
    struct Context {
        v8::Persistent<v8::Context> ctx;
    };
    
    void init_v8_platform() {
        v8::V8::InitializePlatform(v8::platform::CreateDefaultPlatform(1));
        v8::V8::Initialize();
        v8::V8::InitializeICU();
    }
    
    void init_v8_isolate() {
        v8::Isolate::CreateParams params;
        params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
        params.constraints.set_max_old_space_size(20);
        params.constraints.set_max_semi_space_size(20);
        params.constraints.set_max_executable_size(20);
        isolate = v8::Isolate::New(params);
    }
    
    void* init_v8_ctx() {
        v8::HandleScope handle_scope(isolate);
    
        v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
    
        v8::Local<v8::Context> ctx = v8::Context::New(isolate, NULL, global);
    
        Context* v8_ctx = new Context;
        v8_ctx->ctx.Reset(isolate, ctx);
    
        return v8_ctx;
    }
    
    char* read_template(char* template_path, size_t* buff_size) {
        struct stat st;
        if (stat(template_path, &st)) {
            printf("failed to stat file");
            exit(0);
        }
        FILE *f = fopen(template_path, "rb");
        if (f == NULL) {
            printf("no file found");
            exit(0);
        }
        char* buff = (char*) malloc(st.st_size*sizeof(char));
        *buff_size = st.st_size;
    
        int res = 0;
        do {
            if (fread((void*) buff, *buff_size, 1, f) != 1) {
                break;
            }
            res = 1;
        } while(0);
    
        if (res == 0) {
            printf("failed to read file");
            exit(0);
        }
    
        return buff;
    }
    
    int expand_template(void* v8_ctx, char* buff) {
        //printf("%s", buff);
        v8::HandleScope handle_scope(isolate);
    
        v8::TryCatch tc(isolate);
    
        Context* ct = (Context*)v8_ctx;
        v8::Local<v8::Context> ctx = v8::Local<v8::Context>::New(isolate, ct->ctx);
        v8::Context::Scope context_scope(ctx);
    
        v8::MaybeLocal<v8::String> script = v8::String::NewFromUtf8(isolate, buff);
        if (script.IsEmpty()) {
            return 1;
        }
    
        v8::Local<v8::String> s = script.ToLocalChecked();
        //printf("%s\n", *buff);
    
        v8::MaybeLocal<v8::Script> scr = v8::Script::Compile(ctx, s);
        if (scr.IsEmpty()) {
            return 1;
        }
    
        v8::Local<v8::Script> sc = scr.ToLocalChecked();
        v8::MaybeLocal<v8::Value> res = sc->Run(ctx);
        if (res.IsEmpty()) {
            return 1;
        }
    
        if (tc.HasCaught()) {
         //   printf("%s:%s", "HasCaught exception");
        }
    
        return 0;
    }
    
    int expand_forever(void* v8_ctx, char* template_path) {
        size_t buff_size = 0;
        char* buff = read_template(template_path, &buff_size);
    
        int res;
        for (;;) {
            res = expand_template(v8_ctx, buff);
            if (res != 0) {
                printf("%s", "failed to expand template");
            } else {
                printf("%s\n", "success");
            }
        }
    
        free(buff);
    }
    
    void serve(int children, char* template_path) {
        if (children == 0) {
            init_v8_isolate();
            void* ctx = init_v8_ctx();
            expand_forever(ctx, template_path);
        }
    
        for (int i = 0; i < children; i++) {
            pid_t pid = fork();
            switch (pid){
            case -1:
                printf("%s\n", "failed to fork");
                exit(0);
            case 0:
                printf("%s\n", "forking");
                init_v8_isolate();
                void* ctx = init_v8_ctx();
                expand_forever(ctx, template_path);
            }
        }
        for (;;) {}
    }
    
    int main(int argc, char* argv[]) {
        init_v8_platform();
        char* template_path = "test.js";
    
        serve(5, template_path);
        return 0;
    }
    

0 个答案:

没有答案