编译安装v8引擎
‘壹’ nodejs windows下安装模块报错没有node-waf命令
Nodejs使用Google的V8javascript引擎来驱动,因此你需要安装V8引擎。
‘贰’ 如何在Windows下开发NodeJS的C/C++原生扩展
一、编写Node.js原生扩展
Node.js是一个强大的平台,理想状态下一切都都可以用javascript写成。然而,你可能还会用到许多遗留的库和系统,这样的话使用c++编写Node.JS扩展会是一个不错的注意。
以下所有例子的源代码可在node扩展示例中找到 。
编写Node.js C + +扩展很大程度上就像是写V8的扩展; Node.js增加了一些接口,但大部分时间你都是在使原始的V8数据类型和方法,为了理解以下的代码,你必须首先阅读V8引擎嵌入指南。
Javascript版本的Hello World
在讲解C++版本的例子之前,先让我们来看看在Node.js中用Javascript编写的等价模块是什么样子。这是一个最简单的Hello World,也不是通过HTTP,但它展示了node模块的结构,而其接口也和大多数C++扩展要提供的接口差不多:
HelloWorldJs = function() {
this.m_count = 0;
};
HelloWorldJs.prototype.hello = function()
{
this.m_count++;
return “Hello World”;
};
exports.HelloWorldJs = HelloWorldJs;
正如你所看到的,它使用prototype为HelloWorldJs类创建了一个新的方法。请注意,上述代码通过将HelloWorldJS添加到exports变量来暴露构造函数。
要在其他地方使用该模块,请使用如下代码:
var helloworld = require(‘helloworld_js’);
var hi = new helloworld.HelloWorldJs();
console.log(hi.hello()); // prints “Hello World” to stdout
C++版本的Hello World
要开始编写C++扩展,首先要能够编译Node.js(请注意,我们使用的是Node.js 2.0版本)。本文所讲内容应该兼容所有未来的0.2.x版本。一旦编译安装完node,编译模块就不在需要额外的东西了。
完整的源代码可以在这里找到 。在使用Node.js或V8之前,我们需要包括相关的头文件:
#include <v8.h>
#include <node.h>
using namespace node;
using namespace v8;
在本例子中我直接使用了V8和node的命名空间,使代码更易于阅读。虽然这种用法和谷歌的自己的C++编程风格指南相悖,但由于你需要不停的使用V8定义的类型,所以目前为止的大多数node的扩展仍然使用了V8的命名空间。
接下来,声明HelloWorld类。它继承自node::ObjectWrap类 ,这个类提供了几个如引用计数、在V8内部传递contex等的实用功能。一般来说,所有对象应该继承ObjectWrap:
class HelloWorld: ObjectWrap
{
private:
int m_count;
public:
声明类之后,我们定义了一个静态成员函数,用来初始化对象并将其导入Node.js提供的target对象中。设个函数基本上是告诉Node.js和V8你的类是如何创建的,和它将包含什么方法:
static Persistent<FunctionTemplate> s_ct;
static void Init(Handle<Object> target)
{
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New);
s_ct = Persistent<FunctionTemplate>::New(t);
s_ct->InstanceTemplate()->SetInternalFieldCount(1);
s_ct->SetClassName(String::NewSymbol(“HelloWorld”));
NODE_SET_PROTOTYPE_METHOD(s_ct, “hello”, Hello);
target->Set(String::NewSymbol(“HelloWorld”),
s_ct->GetFunction());
}
在上面这个函数中target参数将是模块对象,即你的扩展将要载入的地方。(译着:这个函数将你的对象及其方法连接到
这个模块对象,以便外界可以访问)首先我们为New方法创建一个FunctionTemplate,将于稍后解释。我们还为该对象添加一个内部字段,并命
名为HelloWorld。然后使用NODE_SET_PROTOTYPE_METHOD宏将hello方法绑定到该对象。最后,一旦我们建立好这个函数模板后,将他分配给target对象的HelloWorld属性,将类暴露给用户。
接下来的部分是一个标准的C++构造函数:
HelloWorld() :
m_count(0)
{
}
~HelloWorld()
{
}
接下来,在::New 方法中V8引擎将调用这个简单的C++构造函数:
static Handle<Value> New(const Arguments& args)
{
HandleScope scope;
HelloWorld* hw = new HelloWorld();
hw->Wrap(args.This());
return args.This();
}
此段代码相当于上面Javascript代码中使用的构造函数。它调用new HelloWorld
创造了一个普通的C++对象,然后调用从ObjectWrap继承的Wrap方法,
它将一个C++HelloWorld类的引用保存到args.This()的值中。在包装完成后返回args.This(),整个函数的行为和
javascript中的new运算符类似,返回this指向的对象。
现在我们已经建立了对象,下面介绍在Init函数中被绑定到hello的函数:
static Handle<Value> Hello(const Arguments& args)
‘叁’ 什么是Google V8 JavaScript引擎
V8是一个由丹麦Google开发的开源JavaScript引擎,用于Google Chrome中。[2]Lars Bak是这个项目的组长。[3]
V8在执行之前将JavaScript编译成了机器码,而非位元组码或是直译它,以此提升效能。更进一步,使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序与V8引擎的速度媲美二进制编译。[4]
传统的javascript是动态语言,又可称之为Prototype-based Language,JavaScript继承方法是使用prototype,透过指定prototype属性,便可以指定要继承的目标。属性可以在运行时添加到或从对象中删除,引擎会为执行中的物件建立一个属性字典,新的属性都要透过字典查找属性在内存中的位置。V8为object新增属性的时候,就以上次的hidden class为父类别,创建新属性的hidden class的子类别,如此一来属性访问不再需要动态字典查找了。
为了缩短由垃圾收集造成的停顿,V8使用stop-the-world, generational, accurate的垃圾收集器。[5]在执行回收之时会暂时中断程序的执行,而且只处理物件堆叠。还会收集内存内所有物件的指标,可以避免内存溢位的情况。V8组译器是基于Strongtalk组译器。[6]。
‘肆’ V8编译生成的机器码究竟是什么
实际上V8的JIT编译器是直接在内存中生成机器码的,并不会先生成文本形式的汇编然后再使用汇编器去转换为机器码。“动态生成机器码”听起来可能有点玄乎,其实根本没啥,就是往内存里写字节,这些字节正好是某些机器码的意思,然后把这块内存当作函数去调用就是了。由于代码自身就是动态生成的,在生成的代码里直接嵌入resolve好的各种值其实就相当于传统编译流程里的“动态链接”的效果。顺手放俩我以前博客的传送门:V8实际上自带一个用C++实现的“汇编器库”用来动态生成机器码。它并不把文本形式的汇编转换为机器码,而是提供一组C++ API,调用这个API的函数就可以在内存里生成机器码来。有兴趣的同学可能会知道,V8的MacroAssembler库源自Animorphic的Strongtalk VM,而Strongtalk VM也是HotSpot JVM的前辈。V8 Design Elements文档里所描述的是最初期的V8的状态。当时的V8只有一个JIT编译器,一个JavaScript函数通常只会被JIT编译一次。这个JIT编译器做的优化也不是很多。后来V8演化为拥有两个JIT编译器,一个初级编译器(baseline compiler,名字叫做Full Code Generator,简称FullCodeGen),和一个优化编译器(optimizing compiler,名字叫做Crankshaft),两个编译器结合在一次构成双层编译。JavaScript函数通常会先被FullCodeGen编译,然后如果还继续执行很多次的话则会再被Crankshaft重新编译一遍,生成更优化的代码。在这个架构中,FullCodeGen里生成的代码还是跟V8 Design Elements的相似,会通过inline cache来实现property access;而这些inline cache不但用于实现fast property access,更重要的是它们会被用于收集profile,然后等到Crankshaft编译的时候,它就可以看先前收集的profile来做profile-guided optimization。以这个 function foo(p) { return p.x } 为例,参数p没有任何特别的地方,所以JavaScript引擎也无法知道p到底可能有怎样的值。但通过FullCodeGen生成的代码所收集到的profile信息,Crankshaft再去编译 foo() 的时候就可以知道p之前通常指向一个Map(hidden class)为0x2c97ccb179d1的类型的对象。这个类型的constructor为Point、[[Prototype]] 为Point.prototype、对象里有足够空间容纳10个内嵌的字段(in-object property),并且其中2个slot被用于存储Smi类型,剩余的8个slot未被使用。
‘伍’ v8引擎可以调用http吗
v8引擎只是个js解释器(当然也有预编译),调用http是具体mole干的事儿,跟V8好像没啥关系。
‘陆’ nodejs v8 新特性——利用N-API编写c++ node扩展
相信为nodejs写过 c++扩展的人,都有过nodejs版本升级之后c++需要重新编译的惨痛经历。nodejs v8.0之后node官方推出了N-API 大大的解决了这一问题。
N-API 是独立于v8引擎之外的模块。用来向c++扩展程序提供接口,从而达到了c++扩展程序和v8引擎的隔离。因此在当nodejs版本变化之后c++扩展程序无需重新编译也能运行。
下面我们来看如何利用N-API为nodejs写一个简单的扩展:
我们的例子只从nodejs方面讲起。nodejs版本为8.x 。
首先安装 node-gyp 用来编译我们的扩展程序
‘柒’ Vue/React 项目运行或者打包出现内存溢出解决方案
因为项目过大运行打包项目的时候报错FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
failed - JavaScript heap out of memory JavaScript堆内存不足,这里说的 JavaScript 其实就是 Node,我们都知道 Node 是基于V8引擎,在一般的后端开发语言中,在基本的内存使用上没有什么限制,在 Node 中通过 JavaScript 使用内存时只能使用部分内存(64位系统下约为1.4 GB,32位系统下约为0.7 GB),这就是我们编译项目时为什么会出现内存泄露了,因为前端项目如果非常的庞大,webpack 编译时就会占用很多的系统资源,如果超出了V8对 Node 默认的内存限制大小就会出现刚刚我截图的那个错误了,那怎么解决呢?V8依然提供了选项让我们使用更多的内存。Node 在启动时可以传递 --max-old-space-size 或 --max-new-space-size 来调整内存大小的使用限制。
React
一般情况如果用过第一种方案成功可以不使用第二种,我是遇到第一种配置内存还不起作用的时候用第二种方案生效。
全局安装increase-memory-limit
命令行cmd窗口运行:npm install -g increase-memory-limit,
进入项目文件夹,运行:increase-memory-limit(只需要执行一次即可)
‘捌’ 请教java程序中如何使用webkit的js引擎
1、设置JS_ENGINE变量。有两个值:jsc,v8。这是最方便的方式
2、如果JS_ENGINE变量没有设置,或者设置的值不是jsc,v8其中的一个的话,这个makefile会选择一个默认的引擎进行编译。
对于默认引擎的选择,主要取决于两个变量ARCH_ARM_HAVE_VFP(是否支持VFP)和USE_ALT_JS_ENGINE(与安装buildbot有关,这里不考虑,略过)。如果ARCH_ARM_HAVE_VFP为true的话,系统默认JS引擎选择v8,否则选择jsc
引擎确定后,接下来把JS引擎编译为.a静态库libv8.a(使用v8引擎)或libjs.a(使用jsc引擎)
最后,编译libwebcore.so
v8引擎位于/external/v8下面,编译libwebcore.so时需要libv8.a。所以,如果是在/external/webkit下面使用mm的话,一定要确保v8已经被编译过了
‘玖’ node_moles中.gitattributes是什么文件
node_moles中.gitattributes是node模块文件。
node模块的安装分为全局模式和本地模式。
Node选择了一种既能提高性能,又能减低开发复杂度的架构。这是一个非常重要的特性。并发编程通常很复杂且布满地雷。Node绕过了这些,但仍提供很好的性能。
主要功能:
V8引擎本身使用了一些最新的编译技术。这使得用Javascript这类脚本语言编写出来的代码运行速度获得了极大提升,又节省了开发成本。对性能的苛求是Node的一个关键因素。 Javascript是一个事件驱动语言,Node利用了这个优点,编写出可扩展性高的服务器。
Node采用了一个称为“事件循环(event loop)”的架构,使得编写可扩展性高的服务器变得既容易又安全。提高服务器性能的技巧有多种多样。
‘拾’ 关于V8引擎 350Z改装
350Z是用来改的 而不是用来换大排量引擎的 shotgun808和yuma_asamis说的都十分有道理 你的这辆350Z要怎么改首先要看你要用它来做什么 而不要盲目的去改 其实日产VQ35DE是日产的当家名机 改装套件也是很多的 只要稍加改动 达成四五百匹应该不成问题 如果您真的是发烧级玩家 那建议换上RB26DETT引擎 此引擎就是着名的GTR R34上用的引擎 改装潜力十分巨大 经历很多年直到今天仍然是改装玩家们追捧的对象 RB26DETT引擎如果你有需要你可以把它改到1000匹 前提是你有足够的钱
前面我提到改车的目的 如果练习漂移 则动力不是第一位的 有500匹左右就已经够用 漂移看的是整车的平衡性 如调校发动机输出特性 底盘 悬架 轮胎 整车重量 以及前后配重的等等 漂移基本上是用不到NOS 可以说完全没那个必要
而如果要是用于直线加速或都市疾走那么大马力就非常必要 即使加装 NOS也无可厚非 其实改装最重要的就在乎平衡二字 原厂的车可以说是最平衡的 如果对其任何一个地方进行改动 就会打破这种平衡 而打破这种平衡之后 就要想方设法的让车子再回到平衡的状态 所以说一个好的改装厂至关重要 不然如果改装不当 那么潜在的危险将无处不在 不过350Z的改装套件已经相当成熟 到正规改装店改装可靠性还是很高的
最后和你说一说日系性能车 和 欧美性能车的区别 众所周知的法拉利 兰博基尼 道奇 雪弗兰交叉火力 布加迪 迈凯轮SLR等等等等 这些车都动辄8缸 12缸 16缸 排量5.0至8.0不等 马力基本都在450P往上百公里加速都是5妙俱乐部成员 极速更在280以上 而日系性能车呢 斯巴鲁STI 三菱EVO 尼桑GTR(老款 因为新款已经和欧美性能车不差上下了)本田NSX
丰田SUPER 马自达RX7等 这些日系性能车 最多也就是搭载六缸引擎 马里都不超过300匹 这与日本以前的法律有关 但也显示出了一种日本的用车文化 那就是不像欧美性能车那样追求大排量多汽缸 而是注重于少汽缸配合涡轮 而在必要时便出现了改装车 可以很负责任的告诉你 一辆改装后七八百匹的GTR 兰博基尼只有连刹车灯都看不到的份
所以说350Z装V8是不现实的 另外碳纤维引擎盖只要是真货 就会有减轻车重的作用 剪刀门的改装则不是一般改装厂能胜任了得 改不好会破坏车的刚性 还会增加危险性 不建议改装
最后祝你早日改好自己的350Z