2014-11-05 40 views
3

我目前正在使用node.js作为控制系统来执行一些相对较大规模的图像机器学习的项目。尽管我试图尽可能优化使用情况,但我的数据不应占用过多的空间,但在尝试执行此操作时,内存很快就会耗尽内存。我的代码很大程度上依赖于承诺和匿名函数来管理管道,我想知道这是为什么我在测试用例中看到疯狂的高使用率。承诺和关闭消耗我所有的记忆?

仅供参考,我使用的是我的测试数据集,可以找到here。训练集由60,000个20x20图像组成。从这些我提取overfeat功能,可以找到这个说明here。这可以归结为每个图像4,096个元素的阵列,所以它们有60,000个。我在redis中缓存所有图像和特征数据。

快速计算告诉我,这里设置的全部功能应该是4096 * 8 * 60000 = 1966080000字节或者appx 1.82GB的内存,假设阵列的每个元素都是64位的javascript数字。图像本身只占用非常小的空间,我不会将它们存储在内存中。但是,当我运行我的代码时,我看到更多的提取/加载后使用的内存为8-10GB。当试图对这些数据进行更多的操作时(比如将其全部打印到JSON文件中,以便确保提取正确)我快速占用计算机上的16GB可用内存,导致节点脚本崩溃。

所以我的一般问题是:为什么我看到如此高的内存使用率?是因为我大量使用承诺/关闭?我可以重构我的代码使用更少的内存,并允许更多的变量被垃圾收集?代码here供审查。请注意,就组织而言,这有点粗糙。

+0

为什么你抛出所有的错误,而不是拒绝相应的承诺?这可能会导致一直未决的承诺,而这些承诺会消耗内存。 – Bergi 2014-11-05 00:44:16

+0

此外,我可以发现一个[延迟反patttern](https://stackoverflow.com/questions/23803743/what-is-the-deferred-antipattern-and-how-do-i-avoid-it),这可能导致类似的错误。 – Bergi 2014-11-05 00:50:03

+0

@Bergi我认为抛出错误会拒绝对我的承诺。另外(据我所知)没有任何错误。 – 2014-11-05 01:23:18

回答

3

您的代码使用"promise"库,这是公平的内存非常记忆,并且不是真正为原始性能而构建的。如果你切换到蓝鸟承诺,你可以在RAM中获得更多的项目,因为它会大大减少你的内存使用量。

这里有doxbee顺序基准测试结果:

results for 10000 parallel executions, 1 ms per I/O op 

file         time(ms) memory(MB) 
promises-bluebird.js      280  26.64 
promises-then-promise.js     1775  134.73 

,并在台式平行(--P 25):

file        time(ms) memory(MB) 
promises-bluebird.js      483  63.32 
promises-then-promise.js    2553  338.36 

你可以看到the full benchmark here