使用J2V8改进了内存管理
前言:本文章只是个人翻译自用,不喜欢者勿喷
最近在研究android与js交互
奈何本人能力有限,又是英语渣渣,特用机译方便理解
J2V8中的内存管理从未如此轻松。因为J2V8是V8和Java的桥梁,所以正在使用三种不同的内存模型。Java和JavaScript都通过自己的GC提供了托管内存模型。位于中间的JNI / C ++完全不受管理。这导致了一个复杂的情况,因为JavaScript和Java都会在认为内存未使用但彼此不了解的情况下释放内存。为了解决这个问题,J2V8承担了Java开发人员的责任,以指定应保留哪些对象以及可以释放哪些对象。
但是,记住释放所有V8Objects既容易出错又乏味。在J2V8 4.5中,引入了新的MemoryManager。
一旦实例化,MemoryManager被认为是活动的,并将跟踪所有V8Object。当的MemoryManager被释放时,所有跟踪的对象也将被释放。作为开发人员,您可以在块的开头创建MemoryManager的实例,执行几个J2V8调用,最后在块的末尾释放MemoryManager。按照这种模式,可以确保在执行该块期间没有内存泄漏。
下面是一个使用Node.js和lodash来操作某些对象的简单示例。在此示例中,必须手动跟踪和释放每个对象。由于API无法链接,因此这将导致非常冗长的代码。
loDash = nodeJS.require(new File("/Users/irbull/node_modules/lodash"));
V8Object o1 = o("a", 1);
V8Object o2 = o("b", 2);
V8Object o3 = o("c", 3);
V8Object objects = (V8Object) loDash.executeJSFunction("assign", o1, o2, o3);
LoDashObject e1 = loDash(objects);
LoDashObject e2 = e1.e("values");
V8Function f = f((V8Object receiver, V8Array parameters) -> parameters.getInteger(0) * 3);
LoDashObject result = e2.e("map",f);
System.out.println(result);
loDash.release();
e1.release();
e2.release();
f.release();
o1.release();
o2.release();
o3.release();
result.release();
objects.release();
使用新的MemoryManager,此代码中的API大大简化了。
MemoryManager scope = new MemoryManager(v8);
loDash = nodeJS.require(new File("/Users/irbull/node_modules/lodash"));
V8Object objects = (V8Object) loDash.executeJSFunction("assign", o("a", 1), o("b", 2), o("c", 3));
LoDashObject result = loDash(objects).e("values").e("map",
f((V8Object receiver, V8Array parameters) -> parameters.getInteger(0) * 3));
System.out.println(result);
scope.release();
在此示例中,在该块的开头创建了一个MemoryManager。对lodash的所有调用都可以内联执行,并且所有API调用都已链接。最后,释放MemoryManager,并释放在该块期间分配的所有V8句柄。
如果您希望保留一些对象以备将来使用,MemoryManager将提供一个持久性 API。例如,我们可以在结果对象上使用它。
MemoryManager也可以嵌套。在输入和离开新范围时,可以创建一个新的MemoryManager来管理该范围内的对象。所有以前的MemoryManager都会收到有关所有新对象创建和删除的通知。