2.1k Aufrufe
Gefragt in Skripte(PHP,ASP,Perl...) von kicia Mitglied (939 Punkte)
Hallo,

beim Versuch ein sehr großes Array aufzubauen, stoppt Firefox (anscheinend) die Scriptausführung, ohne Fehlermeldung.
Die Seite ist weiterhin benutzbar.

Kann jemand erklären:
- wie kann man Erfolg oder Fehlschlag des Befüllens erkennen/auswerten?
- wonach richtet sich die maximale länge?
- warum keine Fehlermeldung?

Details:
Firefox stoppt bei mir wenn die Ziellänge des Arrays etwa bei 50.000.000 liegt,
dieser Wert variiert aber nach mir nicht bekannten Regeln.

Zum Vergleich:
Opera bricht das Script genau bei 33.554.433 mit sinnvoller Fehlermeldung ab (33.554.432 ist 2^25).
IE brauch so lange, dass ich noch nicht die Gedult hatte,
das auszutesten (und verbraucht Gigabytes an Speicher).

test Code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>notitle</title>
<script type="text/javascript">

function msg( s ){
var elm = document.getElementsByTagName('body')[0];
elm.appendChild( document.createTextNode( s ) );
}

function startText() {
msg( 'start ' );
window.setTimeout( test, 1000 );
}

function test() {
var out = [];
for( var i = 0; i < 50000000; i++ ){
out.push( 1 );
}
msg('done, ' + out.length);
}
</script>
</head>
<body><input type="button" onclick="startText()" value="start" /></body>
</html>

5 Antworten

0 Punkte
Beantwortet von supermax Experte (4.8k Punkte)
Ich denke es spielen hier mehrere Faktoren eine Rolle
- die verwendete JavaScript-Engine und damit verbunden die maximale Speichergröße, die der Engine zur Verfügung steht
- verfügbarer Hauptspeicher
- es gibt wohl ein im entsprechenden ECMAScript-Standard definiertes Limit von maximal 2^32 Einträgen (also 32 bit vorzeichenlose Arrayindices). Aufgrund der oben genannten Einschränkungen ist dieses Limit allerdings i.d.R. schon früher erreicht. Alte Versionen des IE scheinen z.B. überhaupt nur 16bit-Indices zu unterstützen.

Aber warum brauchst du überhaupt so riesige JavaScript-Arrays?
0 Punkte
Beantwortet von kicia Mitglied (939 Punkte)
Hast Du 'ne Idee, wie man kontrollieren kann, was beim überschreiten des Limits passieren soll ?
(muss zugeben, dass ich es mit try() noch gar nicht versucht habe, fällt mir gerade auf)

Aber warum brauchst du überhaupt so riesige JavaScript-Arrays?


Ich lade einen unicode text und konvertiere jedes zeichen einzeln in ascii.

Also:
iteration über alle Zeichen, ergebnis an myArray anhängen, return myArray.join('').

In dem Text sind Zahlen enthalten, die ich als Integer brauche (parseInt), und ich will in dem Text mit indexOf() suchen.

Ich wollte vermeiden, String operationen für unicode neu schreiben zu müssen.

Bin auch dazu für Kommentare offen.
0 Punkte
Beantwortet von supermax Experte (4.8k Punkte)
Nachtrag: eine 32bit-Applikation (wie die meisten Browser) kann unter Windows (ohne spezielle Einstellungen wie /3GB oder LargeAddressAware) maximal 2 GB adressieren (die anderen 2 GB sind für das Betriebssystem reserviert). Da Integer in JavaScript eigentlich als Fließkommazahlen ohne Nachkommaanteil gespeichert werden, belegt jedes Arrayelement in deiner Schleife mindestens 8 bytes. Selbst wenn man den kompletten Speicher nur für das Array nutzen könnte (was nicht der Fall ist, da ja die Applikation selbst auch noch Speicher benötigt etc.), kann dein Array rein rechnerisch maximal 268.435.456 Einträge aufnehmen.
0 Punkte
Beantwortet von supermax Experte (4.8k Punkte)
JavaScript arbeitet m.W. intern ohnehin mit Unicode.
0 Punkte
Beantwortet von kicia Mitglied (939 Punkte)
Danke für Deine Mühe.
Interessante Informationen.

JavaScript arbeitet m.W. intern ohnehin mit Unicode.

Das nützt mir leider nichts bei Operationen wie zB.
"u n i c o d e S t r i n g".indexOf("String")
..., was natürlich immer -1 ergibt.

Ich werd mal versuchen, mir ein UnicodeString() Objekt zu bauen, mal sehen.
Oder ich lade 64 kB blöcke ...
...