javascript - JavaScript 中的内存管理技术
问题描述
TL;DR -- 从内存管理的角度来看,这两种返回值的方法有什么区别?它们在游戏循环中进行管理,每秒修改数千次。
return { x: x1 + x2, y: y1 + y2, z: z1 + z2 }
// VS
predeclared.x = x1 + x2;
predeclared.y = y1 + x2;
predeclared.z = z1 + x2;
return predeclared;
感谢您的任何见解!
一些上下文......在某些情况下,在 webGL / three.js 程序中,预先声明一个虚拟引用是有益的,该引用将用于在每一帧临时保存一个对象,而不是创建一个新对象来帮助垃圾收集。我很确定这是一种常见的做法,但以防万一它看起来像这样:
let mesh;
while( true ) {
mesh = getNewMeshFrame( time );
renderStuff( mesh );
}
我不确定在以下情况下使用的正确技术。
// With just ONE predeclared object and an object literal in the return statement
function box() {
let box = { x: 0, y: 0 };
this.transform = function( addX, addY ) {
return { x: box.x + addX, y: box.y + addY };
}
}
// OR, with TWO predeclared objects
function box() {
let box = { x: 0, y: 0 };
let transformed = { x: 0, y: 0 };
this.transform = function( addX, addY ) {
transformed.x = box.x + addX;
transformed.y = box.y + addY;
return transformed;
}
}
我希望很明显,盒子对象是静态的并且不能改变(它是一个更复杂的对象 IRL),所以我需要将它与它的变换分开。谢谢!
解决方案
每次transform()
调用返回对象字面量的版本都会分配一个新对象。这些将随着时间的推移在内存中累积,最终需要进行垃圾收集以删除不再使用的那些。
带有预声明变量的版本每次调用时都会返回对同一对象的引用。所以应该有更少的内存积累,更少的垃圾收集需求。但是,这意味着如果您将多个调用分配给不同的变量,它们都是对同一个对象的引用,该对象正在被修改。
b = new box();
t1 = b.transform(1, 2);
t2 = b.transform(3, 4);
与第一个版本,t1
并且t2
是不同的对象:
t1 = {x: 1, y: 2}
t2 = {x: 3, y: 4}
在第二个版本中,它们是同一个对象:
t1 = t2 = {x: 3, y: 4}
如果这对程序的其余部分没有问题,那么如果您transform()
在同一个盒子上多次调用,第二个版本应该会显着提高内存效率。
但是,不同的盒子之间没有共享。
b1 = new box();
b2 = new box();
b1.transform()
在这两个版本中,和之间没有冲突b2.transform()
。
推荐阅读
- arrays - 移动到另一个数组时,如何获取数组的索引并“粘贴”它?
- javascript - 桑基图节点从低到高排序
- erlang - 二叉树的 Erlang 通用 foldl/3 等效项
- python - -bash: image-scraper: 找不到命令
- python - Python - selenium - 无法获取 xpath
- linux - linux内核中的parse_early_parm函数
- reactjs - 使用 React Hooks 设置状态后如何访问状态?
- selenium - 迁移到 WSL 后,Selenium 不再工作。由于 SessionNotCreatedException
- c - 同一程序的不同变体中没有性能差异
- spring-boot - Spring Boot 配置属性验证不起作用