简体   繁体   English

JavaScript中的性能内存管理

[英]Performance Memory Management in JavaScript

Let me start with the questions, and then fill in the reasons/background. 让我先从问题开始,然后填写原因/背景。

Question: Are there any memory profiling tools for JavaScript? 问题:是否有适用于JavaScript的内存分析工具?

Question: Has anybody tested performance memory management in JavaScript already? 问:有没有人在JavaScript中测试性能内存管理?

I would like to experiment with performance memory management in JavaScript. 我想在JavaScript中尝试性能内存管理。 In C/C++/Assembly I was able to allocate a region of memory in one giant block, then map my data structures to that area. 在C / C ++ / Assembly中,我能够在一个巨型块中分配一个内存区域,然后将我的数据结构映射到该区域。 This had several performance advantages, especially for math heavy applications. 这有几个性能优势,特别是对于数学繁重的应用程序。

I know I cannot allocate memory and map my own data structures in JavaScript (or Java for that matter). 我知道我无法分配内存并在JavaScript(或Java)中映射我自己的数据结构。 However, I can create a stack/queue/heap with some predetermined number of objects, for example Vector objects. 但是,我可以使用一些预定数量的对象创建堆栈/队列/堆,例如Vector对象。 When crunching numbers I often need just a few such objects at any one time, but generate a large number over time. 在处理数字时,我经常在任何时候只需要几个这样的对象,但随着时间的推移会产生大量的数据。 By reusing the old vector objects I can avoid the create/delete time, unnecessary garbage collection time, and potentially large memory footprint while waiting for garbage collection. 通过重用旧的矢量对象,我可以避免创建/删除时间,不必要的垃圾收集时间,以及等待垃圾收集时可能存在的大量内存占用。 I also hypothesize that they will all stay fairly close in memory because they were created at the same time and are being accessed frequently. 我还假设它们将在内存中保持相当接近,因为它们是在同一时间创建的并且经常被访问。

I would like to test this, but I am coming up short for memory profiling tools. 我想测试一下,但我的内存分析工具很简短。 I tried FireBug, but it does not tell you how much memory the JavaScript engine is currently allocating. 我尝试过FireBug,但它没有告诉你JavaScript引擎当前分配了多少内存。

I was able to code a simple test for CPU performance (see below). 我能够编写一个简单的CPU性能测试(见下文)。 I compared a queue with 10 "Vector" objects to using new/delete each time. 我将一个队列与10个“Vector”对象进行比较,每次都使用new / delete。 To make certain I wasn't just using empty data, I assigned the Vector 6 floating point properties, a three value array (floats), and an 18 character string. 为了确定我不只是使用空数据,我分配了Vector 6浮点属性,三个值数组(浮点数)和一个18个字符的字符串。 Each time I created a vector, using either method, I would set all the values to 0.0. 每次我使用任一方法创建一个向量时,我都会将所有值设置为0.0。

The results were encouraging. 结果令人鼓舞。 The explicit management method was initially faster, but the javascript engine had some caching and it caught up after running the test a couple times. 显式管理方法最初速度更快,但javascript引擎有一些缓存,并且在运行测试几次后它就赶上了。 The most interesting part was that FireBug crashed when I tried to run standard new/delete on on 10 million objects, but worked just fine for my queue method. 最有趣的部分是当我尝试在1000万个对象上运行标准的new / delete时,FireBug崩溃了,但是对于我的队列方法工作得很好。

If I can find memory profiling tools, I would like to test this on different structures (array, heap, queue, stack). 如果我能找到内存分析工具,我想在不同的结构(数组,堆,队列,堆栈)上测试它。 I would also like to test it on a real application, perhaps a super simple ray tracer (quick to code, can test very large data sets with lots of math for nice profiling). 我还想在一个真实的应用程序上测试它,也许是一个超级简单的光线跟踪器(快速编写代码,可以测试非常大的数据集,其中有大量的数学用于很好的分析)。

And yes, I did search before creating this question. 是的,我在创建这个问题之前就进行了搜索。 Everything I found was either a discussion of memory leaks in JavaScript or a discussion of GC vs. Explicit Management. 我发现的一切都是讨论JavaScript中的内存泄漏或讨论GC与显式管理。

Thanks, JB 谢谢,JB

Standard Method 标准方法

function setBaseVectorValues(vector) {
    vector.x = 0.0;
    vector.y = 0.0;
    vector.z = 0.0;
    vector.theta = 0.0;
    vector.phi = 0.0;
    vector.magnitude = 0.0;
    vector.color = [0.0, 0.0, 0.0];
    vector.description = "a blank base vector";
}

function standardCreateObject() {
    var vector = new Object();
    setBaseVectorValues(vector);

    return vector;
}

function standardDeleteObject(obj) {
    delete obj;
}

function testStandardMM(count) {
    var start = new Date().getTime();
    for(i=0; i<count; i++) {
        obj = standardCreateObject();
        standardDeleteObject(obj);
    }
    var end = new Date().getTime();

    return "Time: " + (end - start)
}

Managed Method 管理方法

I used the JavaScript queue from http://code.stephenmorley.org/javascript/queues/ 我使用了来自http://code.stephenmorley.org/javascript/queues/的JavaScript队列

function newCreateObject() {
    var vector = allocateVector();
    setBaseVectorValues(vector);

    return vector;
}

function newDeleteObject(obj) {
    queue.enqueue(obj);
}

function newInitObjects(bufferSize) {
    queue = new Queue()
    for(i=0; i<bufferSize; i++) {
        queue.enqueue(standardCreateObject());
    }
}

function allocateVector() {
    var vector
    if(queue.isEmpty()) {
        vector = new Object();
    }else {
        vector = queue.dequeue();
    }

    return vector;
}

function testNewMM(count) {
    start = new Date().getTime();
    newInitObjects(10);
    for(i=0; i<count; i++) {
        obj = newCreateObject();
        newDeleteObject(obj);
        obj = null;
    }
    end = new Date().getTime();

    return "Time: " + (end - start) + "Vectors Available: " + queue.getLength();
}

The chrome inspector has a decent javascript profiling tool. chrome检查器有一个不错的javascript分析工具。 I'd try that... 我试试......

I have never seen such a tool but, in actuality, javascript [almost] never runs independently; 我从来没有见过这样的工具,但实际上,javascript [几乎]从不独立运行; it is [almost] always hosted within another application (eg your browser). 它[几乎]总是托管在另一个应用程序(例如您的浏览器)中。 It does not really matter how much memory is associated with your specific data structures, what matters is how the overall memory consumption of the host application is affected by your scripts. 与特定数据结构相关联的内存并不重要,重要的是主机应用程序的整体内存消耗如何受脚本影响。

I would recommend finding a generic memory profiling tool for your OS and pointing it at your browser. 我建议为您的操作系统找一个通用的内存分析工具,并将其指向您的浏览器。 Run a single page and profile the browser's change in memory consumption before and after triggering your code. 运行单个页面并在触发代码之前和之后分析浏览器内存消耗的变化。

The only exception to what I said above that I can think of right now is node.js... If you are using node then you can use process.memoryUsage() . 我刚才能想到的唯一例外是node.js ...如果您使用的是节点,那么您可以使用process.memoryUsage()

Edit: Oooo... After some searching, it appears that Chrome has some sweet tools as well. 编辑: Oooo ...经过一些搜索, Chrome似乎也有一些甜蜜的工具 ( +1 for Michael Berkompas ). Michael Berkompas的+1 )。 I still stand by my original statement, that it is actually more important to see how the memory usage of the browser process itself is affected, but the elegance of the Chrome tools is impressive. 我仍然支持我最初的陈述,看看浏览器进程本身的内存使用情况如何受到影响实际上更为重要,但Chrome工具的优雅性令人印象深刻。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM