Nano Hash - криптовалюты, майнинг, программирование

загрузить файл obj и mtl с помощью three.js OBJMTLLoader.js вызывает утечку памяти после многократной загрузки

Я получаю утечку памяти при загрузке нескольких объектов obj с файлом mtl с помощью three.js, вот мой шаг:

Сначала откройте эту страницу: http://idazhenhan.github.io/threejs/loader/index.html, после загрузки данных нажмите «загрузить», вы увидите несколько желтых сеток на экране, когда вы слегка двигаете мышью;

Затем, если вы используете окна, просто откройте диспетчер задач, посмотрите, сколько памяти занимает вкладка браузера, запишите это.

Наконец, нажмите «обновить» повторно нажмите «загрузить» или «очистить» в верхнем левом углу страницы, снова посмотрите на стоимость памяти в диспетчере задач, вы увидите , память растет и/или казалось никогда не освободится.

Я пишу код релиза в конце index.js, вот он:

function reload() {
    var indexes = [];
    for (var index in scene.children) {
        if(scene.children[index].name.indexOf('test') !== -1){
            indexes.push(scene.children[index]);
        }
    }
    for(var index in indexes){
        scene.remove(indexes[index]);
    }
    load();
};

Я изменил две основные функции:

function load() {
    clear();
    var paths = [];
    for(var i=1;i<=4;i++){
        paths.push({obj: i + '/model_1v.obj', mtl: i + '/model_1v.mtl'});
    }

    var onProgress = function(xhr) {
        if (xhr.lengthComputable) {
            var percentComplete = xhr.loaded / xhr.total * 100;
        }
    };

    var onError = function(xhr) {};

    THREE.Loader.Handlers.add(/\.dds$/i, new THREE.DDSLoader());
    for(var i=0;i<paths.length;i++){
        var path = paths[i];
        var loader = new THREE.OBJMTLLoader();
        loader.load(path.obj, path.mtl, function(model) {
            model.name='test-' + i;
            scene.add(model);
        }, onProgress, onError);
    }
}

function clear() {
    THREE.Cache.clear();
    var models = [];
    for (var i in scene.children) {
        if(scene.children[i].name.indexOf('test') !== -1){
            models.push(scene.children[i]);
        }
    }
    for(var i in models){
        scene.remove(models[i]);
        models[i].traverse(
           function(obj){
                if (obj instanceof THREE.Mesh) {
                    obj.geometry.dispose();
                    obj.material.dispose();
                }
            }, true
        );
    }
    models.length = 0;
};

Но он по-прежнему недействителен, если вас это интересует, вы можете клонировать код здесь: https://github.com/idazhenhan/idazhenhan.github.io.git , затем запустите код на локальном сервере, и вы ясно увидите проблему.

Есть ли кто-нибудь, кто может помочь мне решить эту проблему?


  • В геометрии есть метод dispose(). 27.06.2015
  • Я изменил основную функцию выше, но она по-прежнему недействительна. 27.06.2015
  • взгляните на stackoverflow.com/questions/12945092/ 27.06.2015
  • да, я прочитал ответ несколько дней назад и попробовал этот метод, теперь я обнаружил, что в Three.js есть глобальный кеш, THREE.Cache, я нахожу некоторые данные кеша в его свойстве «файлы», поэтому перед выполнением загрузки (), я вызываю THREE.Cache.clear(), загружается новый код, я вижу, что проблема все еще здесь :( 27.06.2015
  • вы все еще используете функцию reload()? потому что ссылка сверху по-прежнему использует reload(). 27.06.2015
  • ах, извините, страница github.io не обновляется только сейчас, потому что мой адрес электронной почты не подтвержден... теперь код страниц github обновлен, попробуйте еще раз 27.06.2015
  • кажется, что страницы не обновляются правильно, пожалуйста, клонируйте .git на локальный, чтобы проверить 27.06.2015
  • страницы обновлены, если вы все еще заинтересованы в этом, вы можете попробовать еще раз 27.06.2015

Ответы:


1

Для сборщика мусора javascript (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management), чтобы включить все ссылки на объект, должен быть равен нулю. Один из способов сообщить javascript, что вы закончили работу с объектом, — установить для него значение undefined. Кроме того, вам нужно dispose() всю группу объектов внизу. Вот моя версия размещения иерархии.

После вашего звонка scene.remove(models[i]);

Используйте его: disposeHierarchy (object, disposeNode); или disposeNode (node);

var debugging = false;
var indent = "", indent_level = 0;

function disposeNode (node)
{
    if (debugging) console.log (indent_level + " " + indent + "\"" + node.name + "\"");

         if (node instanceof THREE.Camera)
    {
        if (debugging) console.log (indent + "\"" + node.name + "\"" + " " + "\"" + node.type + "\"" + " Camera");

        node = undefined;
    }
    else if (node instanceof THREE.Light)
    {
        if (debugging) console.log (indent + "\"" + node.name + "\"" + " " + "\"" + node.type + "\"" + " Light");

        node.dispose ();
        node = undefined;
    }
    else if (node instanceof THREE.Mesh)
    {
        if (debugging) console.log (indent + "\"" + node.name + "\"" + " " + "\"" + node.type + "\"" + " Mesh");

        if (node.geometry)
        {
            if (debugging) console.log (indent + indent + "I have Geometry");

            node.geometry.dispose ();
            node.geometry = undefined;
        }

        if (node.material)
        {
            if (node.material instanceof THREE.MeshFaceMaterial)
            {
                if (debugging) console.log (indent + indent + "I have many Materials");

                $.each (node.material.materials, function (idx, mtrl)
                {
                    if (mtrl.map)           mtrl.map.dispose ();
                    if (mtrl.lightMap)      mtrl.lightMap.dispose ();
                    if (mtrl.bumpMap)       mtrl.bumpMap.dispose ();
                    if (mtrl.normalMap)     mtrl.normalMap.dispose ();
                    if (mtrl.specularMap)   mtrl.specularMap.dispose ();
                    if (mtrl.envMap)        mtrl.envMap.dispose ();

                    mtrl.dispose ();    // disposes any programs associated with the material
                    mtrl = undefined;
                });
            }
            else
            {
                if (debugging) console.log (indent + indent + "I have Material");

                if (node.material.map)          node.material.map.dispose ();
                if (node.material.lightMap)     node.material.lightMap.dispose ();
                if (node.material.bumpMap)      node.material.bumpMap.dispose ();
                if (node.material.normalMap)    node.material.normalMap.dispose ();
                if (node.material.specularMap)  node.material.specularMap.dispose ();
                if (node.material.envMap)       node.material.envMap.dispose ();

                node.material.dispose ();   // disposes any programs associated with the material
                node.material = undefined;
            }
        }

        node = undefined;
    }
    else if (node instanceof THREE.Object3D)
    {
        if (debugging) console.log (indent + "\"" + node.name + "\"" + " " + "\"" + node.type + "\"" + " Object3D");

        node = undefined;
    }
    else
    {
        if (debugging) console.log (indent + "UNKNOWN " + "\"" + node.name + "\"" + " " + "\"" + typeof node + "\"");
    }
}

function disposeHierarchy (node, callback)
{
    indent += "    ";
    indent_level++;

    for (var i = node.children.length - 1; i >= 0; i--)
    {
        var child = node.children[i];
        disposeHierarchy (child, callback);
        callback (child);
    }

    indent = indent.substr (4); // remove 4 spaces from indent
    indent_level--;
}
27.06.2015
  • ЗДОРОВО ! Использование памяти значительно уменьшилось, большое спасибо! 27.06.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..