......这背后只有一个非常技术性的原因,可能只是因为V8不是用服务器端Javascript开发的吗? 或者是否存在与Node.js的体系结构和性质更相关的原因?有没有理由我应该考虑使用Node.js进行流媒体和管道而不是加载和处理更大量的数据,除了“因为那时你必须增加内存限制”?
答案 0 :(得分:4)
存在限制的主要原因是保护系统的其余部分免受失控内存消费者的影响(即,当您运行多个进程时,其中一个进程会占用它可以获得的所有内存,你希望那个运行到它自己的限制而不是影响系统中的其他所有内容)。对于浏览器场景尤其如此(您不希望一个选项卡占用所有内存而牺牲所有其他选项卡),但也适用于许多服务器端场景。
限制的默认值或多或少是任意的;对于大多数目的而言,它似乎是一种合理的妥协。如果您需要更多,请随意提高它。 64位版本的现代V8版本("现代" =来自最近几年)支持非常大的堆,如果您的应用需要它们。
关于你的上一个问题,"流媒体和管道"无论您是使用Node.js还是任何其他技术,通常都是处理大量数据的有用技术。一次读取所有输入数据的代码往往更容易编写,但总是容易遇到限制: 例如,它运行的机器的物理内存大小。你可以修复"通过购买更多内存,但如果您的代码使用流式传输和合理大小的缓冲区,它将能够以更低的硬件要求处理更大的输入数据,甚至可能运行得更快。
答案 1 :(得分:-1)
目前,V8使用int变量/字段来跟踪内存管理子系统内的各种限制。当堆大小接近1gb时限制溢出,这会导致不稳定的行为
[...]不幸的是,这需要严格重构V8源代码
[...]一个独立的问题是GC吞吐量:虽然目前的V8 GC在小型和中型堆上表现良好[尤其是在满足世代假设的应用程序],但它的性能可能会在大堆上降低。例如,在1.5Gb堆上,应该期望标记扫描取> 1 s [...]
From a chromium bugboard discussion
所以tldr:V8并没有考虑到大js代码,垃圾收集和内存管理是建立在小网站增强器的基础上的。通常情况下,js不能处理大数据。
那么现在该怎么办?即使我们可以增加内存垃圾收集仍然很慢。一些提示:
1)如果你的代码通常是动态的,你应该保持一个平均的内存大小,这样垃圾收集一方面可以处理它,但另一方面不需要经常触发。
2)如果没有,你应该重用数据结构并试图不要停止世界
3)使用Streams和TypedArrays来保持数据不受javascripts的影响。