Isolate
An isolate is a VM instance with its own heap --- 来自官网的简介。
js的虚拟机,是js最大的运行环境。一般一个线程对应一个isolate,当然也可以多线程操作它,但请记得加锁,不然很容易crash,它并非线程安全
Context
Context是js的上下文,A Context中的js变量完全独立于B Context,一般用Context来做js的安全隔离。这里需要区别于Isolate,Context必须依附于Isolate。
Handles & HandleScope
js是由V8自动管理回收内存,具体V8是怎么回收内存的比较复杂,它并不是单纯的标记法或引用计数。
一个handle对应了一个堆上的js native object,HandleScope表示一个管辖范围,位于自己管辖范围的handle的内存由该HandleScope来管理。比如你在创建handle的时候必须在外层显示的说明这个handle是位于哪个HandleScope的“管辖”,这样你就不用操心内存的释放问题了。下图是v8 hello-world的代码:
int main(int argc, char* argv[]) {
// Initialize V8.
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// 省略
}
ScriptCompile & CodeCache
int main(int argc, char* argv[]) {
// 省略
{
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'");
// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(isolate, result);
printf("%s\n", *utf8);
}
// 省略
}
- 得到js代码字符串
- 通过v8::Script::Compile 编译代码
- 执行 run 方法
compile是整个初始化流程里面最耗时的,是启动流程的瓶颈之一。为了优化它,V8后来又推出了code cache,把compile的结果保存,下次直接通过上次compile的结果去得到序列化好的script对象,来减少启动耗时。
src\d8\d8.cc
ScriptCompiler::CachedData* Shell::LookupCodeCache(Isolate* isolate,
Local<Value> source) {
i::ParkedMutexGuard lock_guard(
reinterpret_cast<i::Isolate*>(isolate)->main_thread_local_isolate(),
cached_code_mutex_.Pointer());
CHECK(source->IsString());
v8::String::Utf8Value key(isolate, source);
DCHECK(*key);
auto entry = cached_code_map_.find(*key);
if (entry != cached_code_map_.end() && entry->second) {
int length = entry->second->length;
uint8_t* cache = new uint8_t[length];
memcpy(cache, entry->second->data, length);
ScriptCompiler::CachedData* cached_data = new ScriptCompiler::CachedData(
cache, length, ScriptCompiler::CachedData::BufferOwned);
return cached_data;
}
return nullptr;
}
Snapshot
snapshot可以在运行期对isolate、context拍一个快照,然后存起来。下次启动的时候就直接拿这个快照反序列化出来,直接生成isolate和context,免去了费时的初始化,大大的提升启动速度。
解决启动流程的瓶颈,初始化isolate耗时较高问题
Inspector
Inspector是用于js调试的,它有一套自己的inspect协议,可以把chrome的DevTools作为它的调试客户端,极大的便利了开发者