美好的一天!
存在内存处理问题。我阅读了很多论坛,但仍然无法找到我的代码的错误。
我正在研究项目,我将d3.js与three.js结合起来,可视化节点,如空间轨道上的行星。 我有很多数据 - 比如8个轨道上的8K行星。但是当我尝试加载新数据时 - 我无法在没有内存泄漏的情况下销毁当前树。
我将不胜感激任何帮助!以下是我创建行星的代码的一部分,以及我试图销毁它们的地方:
function initTree(root) {
var start, end;
var nodes = tree.nodes(root); //this is d3.js tree init
var depth = getDepth(root);
var first_x_offset = nodes[0].x;
if (isNaN(first_x_offset)) {first_x_offset = 0}
//create orbits
var orbitTexture = new THREE.ImageUtils.loadTexture('img/orbit_texture.png');
var orbitMaterial = new THREE.MeshBasicMaterial({map: orbitTexture, transparent:true, side: THREE.DoubleSide, alphaTest: 0.05, opacity:0.3});
var sphereGeometry = new THREE.SphereGeometry(1, 6, 6);
var orbitSize = 30;
for (var k=1; k<depth; k++) {
var orbit = new THREE.Mesh(new THREE.CircleGeometry(orbitSize*k, 64), orbitMaterial);
orbit.rotation.x = -90*Math.PI/180;
orbit.name = 'orbit';
scene.add(orbit);
}
//end orbits
//camera position
camera.position.x = 0;
camera.position.y = 70;
camera.position.z = -orbitSize*depth-100;
controls.target.x = 0;
controls.target.y = 0;
controls.target.z = 0;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
//this is parent object to place in center
var parent = new THREE.Object3D();
parent.name = 'parent';
scene.add(parent);
y=0;
spheres = {};
objects = [];
nodes.forEach(function(d) {
if (d.type == 'BLANK') {return}
d.x = d.x - first_x_offset;
if (isNaN(d.x)) {d.x = 0}
var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xdddddd, wireframe: false, opacity: 0.7, transparent: true});
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial );
sphere.material.color.setHex(color_type[d.type]);
sphere.castShadow = false; //maybe change to true
sphere.id2 = y;
d.id2 = y;
sphere.d = d;
sphere.scale.x = radius_type[d.type];
sphere.scale.y = radius_type[d.type];
sphere.scale.z = radius_type[d.type];
sphere.name = 'sphere';
spheres[y] = sphere;
//count items of each type
count_type[d.type]++;
//how many nodes in tree
y++;
//create pivot
var pivot = new THREE.Object3D;
//rotate it
pivot.rotation.y = d.x*Math.PI/180-90;
//append to parent
pivot.name = 'pivot';
parent.add(pivot);
//add mesh to pivot
var default_distance = size/(depth-1);
if (d.y > 0) {
d.y = (Math.round(d.y/default_distance)) * (orbitSize-8.8);
}
sphere.position.x = d.y;
sphere.position.y = 0; //should be 0!
sphere.position.z = d.y;
objects.push(sphere);
pivot.add(sphere);
});
nodesLength = y;
render();
$('.loading').fadeOut(500);
if (!animationId) {
animate();
}
temp = null;
nodes = null;
}
所以我将球体添加到父Object3D,然后将其添加到场景中。
这是破坏功能:
function destroyTree() {
//spheres
//console.log(renderer.info);
var to_delete = [];
for (var i=0; i<spheres.length; i++) {
scene.remove(spheres[i]);
spheres[i].material.dispose();
spheres[i].geometry.dispose();
}
for (var i=0; i<spheres.length; i++) {
spheres[i] = undefined;
}
spheres = {};
for (var i=0; i<objects.length; i++) {
scene.remove(objects[i]);
}
for (var i=0; i<objects.length; i++) {
objects[i] = undefined;
}
objects = [];
var parent = scene.getObjectByName('parent');
scene.remove(parent);
if (links.length) {
for (var i=0; i<links.length; i++) {
scene.remove(links[i]);
}
}
links = [];
scene.traverse(function (child) {
if (child instanceof THREE.Mesh) {
if (child.name.length) {
to_delete.push(child);
}
}
});
for (var i=0; i<to_delete.length; i++) {
scene.remove(to_delete[i]);
to_delete[i].geometry.dispose();
to_delete[i].material.dispose();
to_delete[i] = undefined;
}
to_delete = [];
}
答案 0 :(得分:1)
不会遍历场景也能找到球体吗?在该循环中,您可以直接进行处理,而无需使用to_delete数组。如果所有的spere都不是场景的孩子,那么可能会重新考虑何时创建它们?这些只是优化而且可能做的很少,然后澄清可能泄漏的地方。
然后再次尝试持有纹理数组并直接释放它们?
在这里等一下,这个链接也表示要从渲染器中删除对象和纹理。
renderer.deallocateObject renderer.deallocateTexture