简体   繁体   English

Javascript字符串大小限制:256 MB对我来说 - 对所有浏览器都一样吗?

[英]Javascript string size limit: 256 MB for me - is it the same for all browsers?

Curious about what was the maximum string length I could get in Javascript, I tested it myself, today, on my Firefox 43.0.1, running in Windows 7. I was able to construct a string with length 2^28 - 1 , but when I tried to create a string with one more char, Firebug showed me the "allocation size overflow" error, meaning the string must be less than 256 MB. 想知道我在Javascript中可以获得的最大字符串长度是多少,我今天在我的Firefox 43.0.1上测试了它,在Windows 7中运行。我能够构造一个长度为2^28 - 1的字符串,但是当我试图用另外一个字符串创建一个字符串, Firebug向我展示了“分配大小溢出”错误,这意味着该字符串必须小于256 MB。

Is this the same thing for all browsers, all computers, all operational systems, or it depends? 这对所有浏览器,所有计算机,所有操作系统都是一样的,还是依赖于它?

I created the following snippet to find out the limit: 我创建了以下代码片段以找出限制:

(function() {
    strings = ["z"];
    try {
        while(true) {
            strings.push(strings[strings.length - 1] + strings[strings.length - 1]);
        }
    } catch(err) {
        var k = strings.length - 2;
        while(k >= 0) {
            try {
                strings.push(strings[strings.length - 1] + strings[k]);
                k--;
            } catch(err) {}
        }
        console.log("The maximum string length is " + strings[strings.length - 1].length);
    }
})();

If you are running a different browser/OS, I would like to see your results. 如果您运行的是其他浏览器/操作系统,我希望看到您的结果。 My result was The maximum string length is 268435455 . 我的结果是最大字符串长度是268435455

PS: I searched around for an answer, but the most recent topic I found was from 2011, so I am looking for a more up-to-date information. PS:我四处寻找答案,但我发现的最新话题是2011年,所以我正在寻找更新的信息。

Characters are stored on 16 bits 字符存储在16位

When you see that 256*2**20 characters are in a string, that does not mean that 256 megabytes of memory is allocated. 当您看到字符串中包含256*2**20字符时,这并不意味着分配了256 MB的内存。 JavaScript stores every character on two bytes (as it is utf16 encoded by the specification). JavaScript将每个字符存储在两个字节上(因为它是由规范进行的utf16编码)。

A word about ropes 关于绳索的一个词

Todays browsers (even IE) store strings in an advanced way, most often using a rope datastructure . 今天的浏览器(甚至是IE)以高级方式存储字符串,最常用的是使用绳索数据结构

  • Ropes do not need a coherent memory region to be allocated 绳索不需要分配连贯的存储区域
  • Can even deduplicate substrings, that means s+s does not necessarily use twice the memory as s 甚至可以进行重复数据删除的子串,这意味着s+s不一定使用内存的两倍作为s
  • Concatenation is very fast 连接速度非常快
  • Element access is a bit slower 元素访问速度有点慢

By examining some runs in IE and Chrome, I would say that both of them use some lazy evaluation for strings, and will try to expand them occasionally. 通过检查IE和Chrome中的一些运行,我会说他们都对字符串使用了一些懒惰的评估,并会尝试偶尔扩展它们。 After running the following snippet, none of the browsers used more memory than before. 运行以下代码段后,没有一个浏览器使用的内存比以前多。 But if I tried to manipulate the stored window.LONGEST_STRING in the console, IE throw an out of memory error, and chrome froze for a short time, and consumed a lot of memory (>2 GB). 但是如果我试图在控制台中操纵存储的window.LONGEST_STRING ,IE会抛出一个内存不足错误,并且chrome会冻结一段时间,并消耗大量内存(> 2 GB)。

ps: On my laptop IE11 had a maximum string size of 4 GB, Chrome had 512 MB ps:在我的笔记本电脑上,IE11的最大字符串大小为4 GB,Chrome的容量为512 MB

Browser behaviour 浏览器行为

IE11 IE11

IE11

Chrome47 Chrome47

Chrome47

A faster algorithm to determine max string size 一种更快的算法来确定最大字符串大小

 var real_console_log = console.log; console.log = function(x) { real_console_log.apply(console, arguments); var d = document,b=d.body,p=d.createElement('pre'); p.style.margin = "0"; p.appendChild(d.createTextNode(''+x)); b.appendChild(p); window.scrollTo(0, b.scrollHeight); }; function alloc(x) { if (x < 1) return ''; var halfi = Math.floor(x/2); var half = alloc(halfi); return 2*halfi < x ? half + half + 'a' : half + half; } function test(x) { try { return alloc(x); } catch (e) { return null; } } function binsearch(predicateGreaterThan, min, max) { while (max > min) { var mid = Math.floor((max + min) / 2); var val = predicateGreaterThan(mid); if (val) { min = mid + 1; } else { max = mid; } } return max; } var maxStrLen = binsearch(test, 10, Math.pow(2, 52)) - 1; console.log('Max string length is:'); console.log(maxStrLen + ' characters'); console.log(2*maxStrLen + ' bytes'); console.log(2*maxStrLen/1024/1024 + ' megabytes'); console.log(''); console.log('Store longest string'); window.LONGEST_STRING = alloc(maxStrLen); console.log('Try to read first char'); console.log(window.LONGEST_STRING.charAt(0)); console.log('Try to read last char'); console.log(window.LONGEST_STRING.charAt(maxStrLen - 1)); console.log('Try to read length'); console.log(window.LONGEST_STRING.length); 

A bug report for the chromium tracker has this comment: 铬跟踪器的错误报告有这样的评论:

... When allocation fails, we create a 
Failure pointer encoding the amount requested, as well as some tag and 
type bits. This puts a limit on the maximally possible allocation 
request in 32-bit versions of 2^27-1. The maximal flat string length is 
~2^28 (512MB space), and the maximal string length is 2^29-1...

Note that this is from 2009, so I imagine that this still has consequences in current versions of V8 as the previous link is in regard to a NodeJS tool running into limits of toString() . 请注意,这是从2009年开始的,所以我认为这仍然会对当前版本的V8 产生影响 ,因为之前的链接是关于运行到toString()限制的NodeJS工具。

Internal implementations can use either UCS2 or UTF16. 内部实现可以使用UCS2或UTF16。 As @hege_hegedus suggested, atleast Firefox uses the Rope structure ( https://dxr.mozilla.org/mozilla-central/search?q=%2Btype-ref%3ARopeBuilder ). 正如@hege_hegedus建议的那样,至少Firefox使用Rope结构( https://dxr.mozilla.org/mozilla-central/search?q=%2Btype-ref%3ARopeBuilder )。 The codes give me below results: 代码给出了以下结果:

CHROME VERSION 39.0.2171.95 OS VERSION Linux: 3.13.0-43-generic CHROME VERSION 39.0.2171.95 OS VERSION Linux:3.13.0-43-generic

Firefox 34.0 Firefox 34.0

Chrome output (from @@hege_hegedus code): Max string length is: 268435440 characters 536870880 bytes 511.9999694824219 megabytes Store longest string Try to read first char a Try to read last char a Try to read length 268435440 Chrome输出(来自@@ hege_hegedus代码):最大字符串长度为:268435440字符536870880字节511.9999694824219兆字节存储最长字符串尝试读取第一个字符a尝试读取最后一个字符a尝试读取长度268435440

Firefox output (from OP code): "The maximum string length is 268435455" Firefox输出(来自OP代码):“最大字符串长度为268435455”

Archived at http://gpupowered.org/string_js.txt 存档于http://gpupowered.org/string_js.txt

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

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