Rolf B: ich möchte eine sehr grosse CSV Datei in eine MYSQL Datenbank einspielen

Beitrag lesen

Hallo TS,

Wo liegen eigentlich die Grenzen bei PHP auf 64-Bit-Systemen?

Im physischen Speicher.

Ich habe gerade mal einen kleinen Memory-Hog programmiert und ihm per ini_set ein Speicherlimit von 16G verpasst. Mein physischer Speicher beträgt 8GB, ich habe PHP 8.1 64-bit unter Windows 10 verwendet.

Dann eine Schleife, die ein Array mit 16K langen Strings füllt - solange ich der physischen Speichergröße nicht nahekomme, geht's. Aber dann wird's langsam eng, denn ein lineares Array, das ich immer weiter vergrößere, wird im Speicher regelmäßig umkopiert. Nicht die Inhalte, aber die Array-Kontrollstruktur, und dadurch tobt PHP immer wieder kreuz und quert durch seinen Speicher und lässt ihn nicht unangetastet im pagefile. Mein Windows ist zunächst einmal nicht stehen geblieben, aber es hatte auf einmal immer wieder Aussetzer von 5s-30s. Nicht gut, finde ich, da hat es einem Userprozess zu viel Prio gegeben. Und dabei liegt mein pagefile schon auf einer SSD - eine HDD wäre vermutlich rotglühend geworden.

Und dann kam der Punkt, wo auch 5 Minuten Warten nicht mehr half und ich den Ausschalter betätigen musste. D.h. Memory Overcommitment in einem einzigen PHP Prozess ist nicht gut. Wie es in mehreren parallelen PHP Prozessen aussieht, die in Summe den Speicher overcommitten, habe ich jetzt nicht probiert.

Interessant war aber: Ich konnte für die 16K Strings nicht einfach str_repeat("*", 16384) verwenden. Beim ersten Programmlauf hat er dann brav Speicher belegt, aber ab dem zweiten Lauf ging es deutlich herunter. Offenbar hat der opcache daraus interned strings gemacht und sie wiederverwendet. Mit

$x = "*";
$arr[$i] = str_repeat($x, 16384);

war's mit dem Sparen dann aber wieder vorbei.

Würde mich interessieren, wie Linux damit umgeht.

Hier der Memory Hogger:

<?php
// WARNUNG - NICHT AUF DEINEM WEBSERVER AUSFÜHREN
ini_set("memory_limit", "16384G");
$a = [];
$t = 0;
$mb = 1024*1024;
$chunkSize = 4 * 1024;
for ($c=0; $c<32; $c++) {
    $a[$c] = [];
	for ($i=0; $i<$chunkSize; $i++) {
	    $p = "ABC-";
		$a[$c][$i] = str_repeat($p, 1024 * 4);
		$t += 16*1024;
	}
    printf("Chunk %3d complete - %6.1f MB in %7d strings, use %9.3f MB\n", 
           $c, $t/$mb, ($c+1)*$chunkSize, memory_get_usage()/$mb);
}
echo "Hog complete\n";

Bis $c=80 ging's bei mir, und bei $c=109 ist der PC verstorben 😂

Rolf

--
sumpsi - posui - obstruxi