Mat*_*all 63 javascript memory arrays
我<script>在我的HTML中嵌入了一个大型数组,就像这样(没什么好惊讶的):
<script>
var largeArray = [/* lots of stuff in here */];
</script>
Run Code Online (Sandbox Code Playgroud)
在此特定示例中,阵列具有210,000个元素.这远远低于理论最大值2 31 - 4个数量级.这是有趣的部分:如果我将数组的JS源保存到文件中,那么该文件大于44兆字节(确切地说是46,573,399字节).
如果您想亲眼看看,可以从GitHub下载.(那里的所有数据都是罐装的,所以很多都是重复的.生产中不会这样.)
现在,我真的不担心提供那么多数据.我的服务器gzips它的响应,所以它真的不需要花费很长时间才能通过网络获取数据.但是,一旦加载,页面就会出现令人讨厌的趋势,导致浏览器崩溃.我在IE中根本没有测试(这是一个内部工具).我的主要目标是Chrome 8和Firefox 3.6.
在Firefox中,我可以在控制台中看到一个相当有用的错误:
Error: script stack space quota is exhausted
在Chrome中,我只是得到了悲伤标签页:

顺便说一句,我能够在Chrome中启用此功能(阅读:不会崩溃选项卡).我真的认为Chrome至少是由更强硬的东西制成的,但显然我错了......
@Crayon:我不想证明我为什么要立即将这么多数据转储到浏览器中.简短版本:要么解决这个问题(当然不是那么容易),要么我必须解决一大堆其他问题.我现在选择更简单的方法.
@various:现在,我并不是特别想找到减少数组中元素数量的方法.我知道我可以实现Ajax分页或者你有什么,但是在其他方面它会为我引入一系列问题.
@Phrogz:每个元素看起来像这样:
{dateTime:new Date(1296176400000),
terminalId:'terminal999',
'General___BuildVersion':'10.05a_V110119_Beta',
'SSM___ExtId':26680,
'MD_CDMA_NETLOADER_NO_BCAST___Valid':'false',
'MD_CDMA_NETLOADER_NO_BCAST___PngAttempt':0}
Run Code Online (Sandbox Code Playgroud)
@Will:但是我的计算机配备了4核处理器,6 GB RAM,超过半TB的磁盘空间......我甚至都没有要求浏览器快速完成这项工作 - 我只想问因为它可以工作!☹
任务完成!
通过Juan和Guffa的现场建议,我能够让这个工作!似乎问题只是解析源代码,而不是在内存中实际使用它.
总结胡安答案的评论泥潭:我不得不将我的大阵列分成一系列较小的阵列,然后是Array#concat()它们,但这还不够.我还必须将它们分别var发表.像这样:
var arr0 = [...];
var arr1 = [...];
var arr2 = [...];
/* ... */
var bigArray = arr0.concat(arr1, arr2, ...);
Run Code Online (Sandbox Code Playgroud)
致所有为解决这个问题做出贡献的人:谢谢.第一轮对我来说!
*除了显而易见的事情:向浏览器发送更少的数据
Jua*_*des 82
这是我要尝试的:你说它是一个44MB的文件.这肯定需要超过44MB的内存,我猜这需要超过44MB的RAM,也许是半场演出.您是否可以减少数据直到浏览器不崩溃并查看浏览器使用多少内存?
即使只在服务器上运行的应用程序也能很好地读取44MB文件并将其保存在内存中.说了这么多,我相信浏览器应该能够处理它,所以让我运行一些测试.
(使用Windows 7,4GB内存)
第一次测试 我把阵列切成两半,没有问题,使用80MB,没有崩溃
第二次测试 我将数组分成两个独立的数组,但仍然包含所有数据,使用160Mb,没有崩溃
第三次测试 由于Firefox说它没有堆栈,问题可能是它无法立即解析数组.我创建了两个独立的数组,arr1,arr2然后做了arr3 = arr1.concat(arr2); 它运行良好,仅使用稍多的内存,大约165MB.
第四次测试我正在创建其中7个阵列(每个22MB)并将它们连接起来测试浏览器限制.页面完成加载大约需要10秒钟.内存高达1.3GB,然后又回落到500MB.所以是的铬可以处理它.它只是不能一次解析它,因为它使用某种递归,因为控制台的错误消息可以注意到.
回答创建单独的数组(每个少于20MB),然后连接它们.每个数组都应该在它自己的var语句中,而不是使用单个var进行多个声明.
我仍然会考虑只获取必要的部分,这可能会使浏览器变得迟钝.但是,如果这是一项内部任务,那应该没问题.
最后一点:您没有达到最大内存级别,只是最大解析级别.
Guf*_*ffa 13
是的,要求浏览器太多了.
如果数据已经是数据,那么这些数据将是可管理的,但它还不是数据.考虑到浏览器必须解析那个巨大的源代码块,同时检查语法是否会加起来.解析成有效代码后,代码必须运行才能生成实际数组.
因此,所有数据将同时存在于(至少)两个或三个版本中,每个版本都有一定的开销.由于数组文字是单个语句,因此每个步骤都必须包含所有数据.
将数据划分为几个较小的数组可能会使浏览器更容易.
你真的需要所有数据吗?你不能只使用AJAX流式传输当前需要的数据吗?与谷歌地图类似 - 您无法将所有地图数据放入浏览器的内存中,它们只显示您当前看到的部分.
请记住,在浏览器的内部表示中,40兆的硬数据可以膨胀得更多.例如,JS解释器可以使用散列表来实现数组,这会增加额外的内存开销.此外,我希望浏览器同时存储源代码和JS内存,这仅仅是数据量的两倍.
JS旨在提供客户端UI交互,而不是处理大量数据.
编辑:
顺便说一下,你真的认为用户会喜欢下载40兆字节的代码吗?仍有许多用户使用宽带互联网.并且将暂停执行脚本,直到下载所有数据.
EDIT2:
我查看了数据.该数组肯定会表示为哈希表.此外,许多项目都是对象,需要参考跟踪...这是额外的内存.
我想如果它是原始数据的简单向量,性能会更好.
编辑3:数据当然可以简化.它的大部分是重复的字符串,可以用某种方式编码为整数或其他东西.另外,我的Opera在显示文本时遇到了麻烦,更不用说解释它了.
EDIT4:忘记DateTime对象!使用unix时代的时间戳或字符串,但不使用对象!
编辑5:您的处理器无关紧要,因为JS是单线程的.而且你的RAM也无关紧要,大多数浏览器都是32位,所以它们不能使用大部分内存.
EDIT6:尝试将数组索引更改为顺序整数(0,1,2,3 ......).这可能会使浏览器使用更高效的数组数据结构.您可以使用常量有效地访问数组项.这将通过巨大的块来减少阵列大小.
| 归档时间: |
|
| 查看次数: |
31665 次 |
| 最近记录: |