php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 04.02.2012, 16:48  
Neuer Benutzer
 
Registriert seit: 29.09.2009
Beiträge: 6
PHP-Kenntnisse:
Anfänger
Thomas123 befindet sich auf einem aufstrebenden Ast
Standard Memory-Leak bei ODBC-Verbindung

Hallo,
ich habe eine Anwendung aus der ich Daten über die ODBC-Schnittstelle auslesen möchte.
Dazu habe ich eine entsprechende System-DSN angelegt. Das Auslesen der Daten funktioniert auch alles wie gewünscht.
Jetzt ist beim Testen aufgefallen, dass bei der ODBC Anbindung ein Speicherleck entsteht. Das Ganze läuft unter Windows XP. D.h. je länger die Anwendung läuft, desto mehr Speicherverbrauch wird im Taskmanager angezeigt. Der Speicherbedarf kann ich jedoch keinem Prozess zuordnen. Irgendwann kommt dann eben die Meldung dass kein Speicher mehr vorhanden ist.

Nun habe ich die ODBC-Verbindung mit anderen Programmen ebenfalls getestet, um auszuschließen dass der Fehler auf der Seite liegt die die ODBC Anfrage bearbeitet. Das habe ich mit einem Perl (Win32::ODBC) und einem C# Anwendungsprogramm getestet. Dort tritt kein Speicherleck auf.

Meine php Testprogramme rufe ich aus einer Eingabeaufforderung heraus auf, später soll das im Webserver Kontext laufen-
Das seltsame ist dabei, dass wenn ich die odbc-Aufrufe in eine eigene Funktion oder Klasse lege, ein Speicherleck auftritt. Wenn ich das Ganze direkt in einer Schleife (siehe Testprogramm) aufrufe, dann nicht.

Vielleicht hat jemand ja einen Tip ob ich noch irgendwodran drehen kann, um das Problem zu beheben. Ich habe mich mehr oder weniger schon auf php eingeschossen, und möchte jetzt ungern nur wegen der odbc Probleme alles auf Perl umschreiben müssen.

Das Testprogramm mit Speicherleck:
PHP-Code:
<?php
// mit Speicherleck
error_reporting(E_ALL);
ini_set('display_errors'1);
setlocale(LC_TIME"de_DE");

echo 
"Start...\n";

for (
$i 0$i 100$i++) {
    echo 
"Starte Durchlauf Nr. " . ($i+1) . "\n";
    
test();        
    
sleep(5);
}

function 
test()
{        
    
$conn odbc_connect('DEMO1','''');
    if (!
$conn) {
        echo 
"Fehler";
        return;
    }
    echo 
"Verbunden\n";
    
$sql "SELECT Timestamp, Messwert1_ival, Messwert2_ival FROM Interval2 WHERE (Timestamp>={ts '2012-02-03 00:00:00'} And Timestamp<={ts '2012-02-03 23:59:59'})";
    
$rs odbc_exec($conn$sql);
    
odbc_free_result($rs);
    
odbc_close($conn);
}
?>
Und dieses ohne:
PHP-Code:
<?php
// ohne Speicherleck
error_reporting(E_ALL);
ini_set('display_errors'1);
setlocale(LC_TIME"de_DE");

echo 
"Start...\n";

for (
$i 0$i 100$i++) {
    echo 
"Starte Durchlauf Nr. " . ($i+1) . "\n";
    
$conn odbc_connect('DEMO1','''');
    if (!
$conn) {
        echo 
"Fehler";
        return;
    }
    echo 
"Verbunden\n";
    
$sql "SELECT Timestamp, Messwert1_ival, Messwert2_ival FROM Interval2 WHERE (Timestamp>={ts '2012-02-03 00:00:00'} And Timestamp<={ts '2012-02-03 23:59:59'})";
    
$rs odbc_exec($conn$sql);
    
odbc_free_result($rs);
    
odbc_close($conn);
    
    
sleep(5);
}
?>
Ich habe php Version 5.3.5 laufen. In den Changelogs konnte ich in den aktuelleren Versionen keine Änderungen im odbc-Modul entdecken.

Wenn man nach "odbc" und "memory-leak" googelt, bekommt man dazu auch etliche Texte, allerdings alle etwas älteren Datums.
Bei mir dauert ein odbc_connect() auch sehr lange (bis zu 10 Sekunden), das aber unabhängig ob php, Perl oder mittels C#.

Gruß
Thomas
Thomas123 ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 04.02.2012, 17:22  
Benutzer
 
Registriert seit: 04.09.2009
Beiträge: 34
PHP-Kenntnisse:
Anfänger
cnc_darklord befindet sich auf einem aufstrebenden Ast
Standard

Wenn ich das richtig sehe bekommst du ein Memory Leak, weil pro Test-Funktionsaufruf eine lokale Variable $rs' auf dem Aktivierungsblock angelegt wird. Diese Variablen werden erst zu Skriptende abgeräumt.

Bei deiner Version ohne Funktion hingegen wird immer die gleich Variable $rs überschrieben.

Geändert von cnc_darklord (04.02.2012 um 17:43 Uhr). Grund: $re = $rs
cnc_darklord ist offline   Mit Zitat antworten
Alt 04.02.2012, 17:36  
Neuer Benutzer
 
Registriert seit: 29.09.2009
Beiträge: 6
PHP-Kenntnisse:
Anfänger
Thomas123 befindet sich auf einem aufstrebenden Ast
Standard

Du meinst Variable $rs, oder?

Ich habe nochmal weitergetestet. Das Speicherleck tritt auf auch wenn ich nur ein odbc_connect() und odbc_close() mache, also komplett ohne SQL-Abfrage dazwischen.

Ich habe mir jetzt mal mit print_r($conn) die Verbindungs-IDs ausgeben lassen.
Wenn ein Speicherleck auftritt, bekomme ich immer eine neue Verbindungs-ID. Was bei der Version in der $conn eine lokale Variable ist auch einigermaßen verständlich ist.
Nur ist es wohl so, dass der angeforderte Speicher der lokalen Variable nicht wieder freigegeben wird, erst wenn das Programm beendet wurde, fällt der Speicherbedarf wieder.

Es gibt ja verschiedene Varianten der odbc Verbindung (persistent, nicht persistent). Aber egal welche ich nun verwende, ein Speicherleck darf es doch nicht geben.
Später soll das Ganze als CGI Anwedung im Webserver laufen. Momenten habe ich es in dem server2go Apache/php testweise, da tritt das Speicherleck ebenfalls auf.
Thomas123 ist offline   Mit Zitat antworten
Alt 04.02.2012, 17:44  
Benutzer
 
Registriert seit: 04.09.2009
Beiträge: 34
PHP-Kenntnisse:
Anfänger
cnc_darklord befindet sich auf einem aufstrebenden Ast
Standard

Warum baust du nicht nur einmal (1x) eine Verbindung auf?
Alles andere sieht mir nach einen Logik fehler aus.
cnc_darklord ist offline   Mit Zitat antworten
Alt 04.02.2012, 17:49  
Neuer Benutzer
 
Registriert seit: 29.09.2009
Beiträge: 6
PHP-Kenntnisse:
Anfänger
Thomas123 befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von cnc_darklord Beitrag anzeigen
Warum baust du nicht nur einmal (1x) eine Verbindung auf?
Alles andere sieht mir nach einen Logik fehler aus.
Weil es später in einem Webserver laufen soll. Wie soll denn die Datenbank-Verbindung offen gehalten werden, wenn eine Anfrage von einem neuen Client Minuten/Stunden später kommt?

Wenn ich das hier richtig verstanden habe
http://www.php.net/manual/en/feature...onnections.php
ist das auch von Anwendungstyp (IIS/Apache etc.) verschieden. Aber im Normalfall macht der php Interpreter das Offenhalten einer Verbindung intern.

Ein odbc_pconnect() macht bei mir auch keinen Unterschied, es gibt immer eine neue Verbindungd-ID.
Thomas123 ist offline   Mit Zitat antworten
Alt 04.02.2012, 18:24  
Benutzer
 
Registriert seit: 04.09.2009
Beiträge: 34
PHP-Kenntnisse:
Anfänger
cnc_darklord befindet sich auf einem aufstrebenden Ast
Standard

Das gesehen?
Zitat:
Note: Persistent connections have no effect if PHP is used as a CGI program.
cnc_darklord ist offline   Mit Zitat antworten
Alt 04.02.2012, 18:35  
Neuer Benutzer
 
Registriert seit: 29.09.2009
Beiträge: 6
PHP-Kenntnisse:
Anfänger
Thomas123 befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von cnc_darklord Beitrag anzeigen
Das gesehen?

Note: Persistent connections have no effect if PHP is used as a CGI program.
Ja, ist mir aber auch egal wenn der Verbindungsaufbau ein paar Sekunden dauert, nur stabil muss es laufen.
Wenn ich mein Testprogramm aus der Eingabeaufforderung heraus aufrufe, werden ebenfalls keine persistenten Verbindungen verwendet. In der php.ini ist das aber aktiviert (default).

Ich habe jetzt nochmal ein paar Tests gemacht:
1) unset($conn) und $conn = null -> keine Änderung
2) gc_collect_cycles() -> keine Änderung
3) Umstellung auf PDO -> keine Änderung

Wenn ich mir im Programm mit memory_get_peak_usage() den maximalen Speicherbedarf ausgebe, liegt der immer bei dem gleichen Wert, auch wenn im Windows Taskmanager der Bedarf stetig ansteigt, bis irgendwann php mit Speicherengpass aussteigt.

Mal sehen ob ich testweise eine andere ODBC-Datenquelle einrichten kann, um versuchen das damit nachzustellen. Gibts irgendwas das man relativ einfach einrichten kann?
Thomas123 ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
imagecreatefromjpeg() "Allowed memory size exhausted" peter silie PHP Tipps 2010 17 04.05.2011 14:25
ODBC Verbindung Abfragedaten in Array watchdogg Datenbanken 7 13.01.2011 14:41
Verbindung am Laufen halten Testmodul Software-Design 4 08.12.2010 10:01
Imagick Bildverarbeitung Skript (Memory Leak ?) arthurdent PHP-Fortgeschrittene 9 20.07.2010 19:50
[Erledigt] MySQL Link Resource in einer statischen Variablen speichern Lenki PHP-Fortgeschrittene 8 18.03.2010 16:37
ODBC connect fehler Darn Datenbanken 3 12.08.2009 19:49
MySQL verbindung TeazY PHP Tipps 2008 2 18.12.2007 14:34
Diverses aus meinem Apache Logs robo47 Server, Hosting und Workstations 5 25.05.2007 22:45
Kein Zugriff über ODBC mit der IP-Adresse auf MySql DB Datenbanken 4 09.02.2006 11:04
FTP Verbindung wird abundzu unterbrochen themonk Off-Topic Diskussionen 1 02.01.2006 07:41
persistente MySQL Verbindung und clonen HStev PHP-Fortgeschrittene 16 22.11.2005 13:24
[Erledigt] Access mit ODBC auf Root Server Server, Hosting und Workstations 1 24.09.2005 15:15
Komisches ODBC Problem... solitaer PHP-Fortgeschrittene 0 17.09.2005 18:21
ODBC Bronks Datenbanken 1 30.07.2005 20:09
[Erledigt] Verbindung auf eine Datenbank Datenbanken 5 07.07.2005 20:38

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
c# mehrere odbc verbindungen in einer schleife

Alle Zeitangaben in WEZ +2. Es ist jetzt 16:58 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum