Etwas frist Speicher VDR, Streamdev, SoftHdDevice, ffmpeg, VDPAU? VDR

  • Ein Fix für einen Audio memory leak ist im GIT.


    Great work! I can confirm this fix appears to have resolved the memleak with audio. There still seems to be a memleak on the video side, and also the memory is not fully released when changing channels or stopping a recording playback.


  • Hier 2 memory leaks über die Valgrind im VDR meckert.

    Code
    1. ==22366== 524,320 bytes in 1 blocks are definitely lost in loss record 272 of 273
    2. ==22366== at 0x4A094F6: memalign (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    3. ==22366== by 0x4A09611: posix_memalign (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    4. ==22366== by 0x390321C9F6: ???
    5. ==22366== by 0x5AC5F32: ???
    6. ==22366== by 0x5ABE142: ???
    7. ==22366== by 0x4CFA79: cPluginManager::StartPlugins() (in /usr/bin/vdr)
    8. ==22366== by 0x4695D1: main (in /usr/bin/vdr)


    Tut mir leid, aber ich kann in cPluginManager::StartPlugins() beim besten Willen nichts sehen, was ein Memory-Leak verursachen könnte.
    Kann es sein, daß das in einem Plugin passiert?


    Quote
    Code
    1. ==22366== 1,048,476 bytes in 1 blocks are definitely lost in loss record 273 of 273
    2. ==22366== at 0x4A06F60: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    3. ==22366== by 0x48C300: cNonBlockingFileReader::Request(cUnbufferedFile*, int) (in /usr/bin/vdr)
    4. ==22366== by 0x48E2EB: cDvbPlayer::Action() (in /usr/bin/vdr)
    5. ==22366== by 0x5042EE: cThread::StartThread(cThread*) (in /usr/bin/vdr)
    6. ==22366== by 0x38DEA072C3: start_thread (in /lib64/libpthread-2.20.so)
    7. ==22366== by 0x38DE2E9F4C: clone (in /lib64/libc-2.20.so)
    8. ==22366==


    Da kann es wohl nur um 'buffer' gehen. In cNonBlockingFileReader::Request() wird zwar


    buffer = MALLOC(uchar, wanted);


    gemacht, aber unmittelbar vorher wird Clear() aufgerufen und darin wird


    free(buffer);
    buffer = NULL;


    gemacht. Also ich sehe da kein Memory-Leak.


    Klaus

  • Ich würde einzelne - scheinbar verlorene - Blocks bei der Initialisierung erst mal außer Acht lassen. Das kann nicht das eigentliche Problem sein.


    Alle Tools, mit denen ich experimentiert hatte, hatten Probleme, sobald fork() bzw. Laden von Shared Libraries ins Spiel kamen...


    CU
    Oliver

  • Habe nun valgrind mit der HDFF-Installation auf einer schnellen Maschine eine Zeit lang laufen lassen:

    Code
    1. ==13718== LEAK SUMMARY:
    2. ==13718== definitely lost: 6,784 bytes in 27 blocks
    3. ==13718== indirectly lost: 2,151 bytes in 101 blocks
    4. ==13718== possibly lost: 0 bytes in 0 blocks
    5. ==13718== still reachable: 434,621 bytes in 3,150 blocks
    6. ==13718== suppressed: 0 bytes in 0 blocks


    Die gefunden Leaks hängen alle irgendwie mit fontconfig-Gedöns zusammen:


    Das ganze führt jedoch zu nichts, denn das sind lächerliche ~9 KByte - viel zu wenig!


    Das eigentliche Problem muß imho irgendwo in den "still reachable" Blocks stecken. Nicht alles, was reachable ist, muß auch korrekt sein.


    kls
    Wo könnte man am besten ansetzen, um folgende Komponenten vollständig außer Kraft zu setzen:
    1. OSD-Generierung abschalten (insbesondere keinerlei Fontverarbeitung mehr)
    2. Channel-und CA-Descriptor Update
    3. EPG-Verarbeitung


    Ich würde gerne versuchen, das Problem auf einen Themenkomplex einzukreisen.


    Btw, das ganze ist insofern schwierig, da die HD-FF in einem Produltivsystem steckt. Ein längerer Betrieb mit valgrind kommt selbst auf der schnellen Maschine nicht in Frage, denn die Reaktionszeit des Systems ist völlig inakzeptabel...


    CU
    Oliver

  • Wo könnte man am besten ansetzen, um folgende Komponenten vollständig außer Kraft zu setzen:
    1. OSD-Generierung abschalten (insbesondere keinerlei Fontverarbeitung mehr)


    In osd.c cOsdProvider::NewOsd() alles bis auf das return am Schluß auskommentieren.


    In font.c cFont::CreateFont() alles ersetzen durch


    return new cDummyFont(CharHeight);


    Quote


    2. Channel-und CA-Descriptor Update


    In pat.c cPatFilter::cPatFilter() die Set()-Zeile auskommentieren.


    In sdt.c cSdtFilter::cSdtFilter() die Set()-Zeile auskommentieren.


    In nit.c cNitFilter::cNitFilter() die Set()-Zeile auskommentieren.


    Quote


    3. EPG-Verarbeitung


    In eit.c cEitFilter::cEitFilter() die Set()-Zeilen auskommentieren.


    Klaus

  • Danke, der Aufwand hält sich ja zum Glück in Grenzen.


    Mit den Änderungen 2. + 3. scheint der Speicherbedarf nach einiger Zeit nicht mehr weiter anzuwachsen. Ist allerdings nicht wirklich überraschend, da keine Daten mehr dazukommen.


    Ich werde das ganze jetzt noch einige Zeit laufen lassen und dann in den nächsten Tagen die Änderungen einzeln zurücknehmen...


    CU
    Oliver

  • Bin nicht sicher, ob folgendes die oder eine Ursache unseres Problems ist, ein Bug ist es auf jeden Fall:


    cListBase::Sort() legt ein Array von Pointern auf den Stack, was bei großen Listen problematisch ist:

    Code
    1. int n = Count();
    2. cListObject *a[n];


    Auf 64-Bit Systemen sind Pointer 8 Byte statt 4 Byte groß, daher ist das Array gleich doppelt so groß. Hier hat es gekracht, als ich versucht habe, alle Sendungen auf allen Kanälen anzuzeigen...


    Der angehängte Patch alloziert das Array auf dem Heap.


    CU
    Oliver

  • Warum nicht C++ nutzen, damit es etwas schöner aussieht?


    Lars.

  • Warum nicht C++ nutzen, damit es etwas schöner aussieht?


    Weil VDR in C geschrieben ist... oder? ;) *duck*


  • Tut mir leid, aber ich kann in cPluginManager::StartPlugins() beim besten Willen nichts sehen, was ein Memory-Leak verursachen könnte.
    Kann es sein, daß das in einem Plugin passiert?


    Werde mal gucken, wem die Adressen dazwischen gehören.



    Es scheint darauf anzukommen, wann ich VDR abbreche. Ich habe nun mehre Tage die Aufnahme wiederholt abgespielt.
    Nach einer Stunde wieder neu abspielen lassen, wärend die Aufnahme noch abgespielt wurde.


    Jetzt war dies nicht im log. Nur der cPluginManager::StartPlugins() ist geblieben.


    UFO


    "definitely lost" im valgrind heisst das kein Pointer mehr auf diesen Bereich vorhanden ist.
    Das ist keine Buffer fürs Initialisieren, diese sind "possibly lost".


    Johns

    Sag mir, wo die Developer sind. Wo sind sie geblieben? . . . . . . . . . . . . . . . . . . . . SoftHdDevice - A software and GPU emulated HD output device plugin.
    Sag mir, wo die Developer sind. Was ist geschehn?


    Client0: Crown CW02 MSI_C847MS-E33 Zotac_GT640_passiv Cine-S2 iMon-MCE / streamdev softhddevice
    Client1: Lian_Li_PC-Q09FB ASRock_H67M-ITX/HT I3-2100 ASUS_ENGT520_passiv / streamdev softhddevice
    Test: Lian_Li_PC-Q09R Asus C60M1-I / streamdev
    Server0: Dockstar TT-S2-3600-USB / streamdev
    Server2: Lian_Li_PC-Q07R Intel_DH61DL G620 WD20EARX 90W PicoPSU Cine-S2+DuoFlex-S2+DuoFlex-CT / streamdev / 22 Watt Verbrauch

  • Also ich finde "free" hoert sich viel besser an als "delete" :D


    Ich bin für boost::shared_ptr, da braucht man beides nicht.


    Gerald


    HP Proliant MicroServer Gen8, Xeon E3-1230, 12 GB RAM, 3xWD red 2TB im RAID 5, 2xSundtek MediaTV Home DVB-C/T, L4M TWIN-C/T, Ubuntu Server 14.04.1, Plex Media Server
    Samsung UE55H6470

  • Ob new oder malloc, ist sch...egal. Wenn ich zu wählen habe, würde ich - in diesem Fall - malloc nehmen, denn Sort() hat nicht viel mit C++ zu tun. Da brauche ich nicht ausgerechnet für die Allokation C++ zu nehmen. (Außerdem fange ich bei new immer an zu überlegen, ob da nicht irgendwelche Konstruktoren mit ausgeführt werden...)


    Allen, die Lust haben, sich mit solchen Nichtigkeiten aufzuhalten, empfehle ich, ihre Energie in die Fehlersuche zu investieren. Da kommt man gleich auf ganz andere Gedanken. :wow


    Es sieht nämlich nicht so aus, als ob hiermit der eigentliche Fehler behoben wäre. Es war nur ein Nebenprodukt der Fehlersuche.


    Bei der riesigen Menge an Allokationen/Deallokationen, die in VDR stattfinden, muß man mit einer Fragmentierung des Heaps rechnen. Ein Anwachsen des Speicherbedarfs bedeutet also erst mal nicht notwendigerweise, dass es ein Speicherleck gibt. Es sieht allerdings verdächtig danach aus.


    valgrind findet jedoch nichts. Dies bedeutet, dass valgrind es entweder übersieht, oder die Blöcke nicht wirklich verloren sind und in irgendwelchen Datenstrukturen/Listen herumgammeln.


    CU
    Oliver

  • Danke, UFO, für den Patch. Ich bin allerdings ab morgen bis 11. Juli in Urlaub und komme erst danach wieder dazu, am VDR zu arbeiten.


    Dann wünsche ich schon mal einen schönen Urlaub!


    Quote


    Ein Grund, 64-Bit zu meiden, wenn man es nicht unbedingt braucht ;-).


    Ist leider nicht ganz so einfach. Wie ich feststellen musste, läuft das 32-Bit dvbhddevice nicht mit dem 64-Bit Treiber. Da gibt's Probleme - vermutlich infolge der unterschiedlichen Größe von "Ptr" und "long". -> Andere Baustelle.


    CU
    Oliver

  • Ich weiss nicht, ob das bekannt ist, aber die EPG-Daten "fressen" eine Menge Speicher.


    VDR 2.2.0 + DvbSdDevice-Plugin + minimales EPG (epg.data < 1MB) => ca. 25MB RAM
    Identisches Setup, nur andere epg.data mit ~ 40MB (komplettes EPG von Astra 19.2°) => ca. 105MB RAM :wow .


    Mit einem gewissen Overhead hätte ich gerechnet, aber das wären 100%.
    Das ist übrigens auf einem 64-Bit Linux. Eventuell ist das die Ecke, wo der VDR unter 64Bit so viel mehr Arbeitsspeicher braucht?

    Gruss
    SHF


  • Da sind eine Menge Pointer im Spiel und die sind bei 64Bit nun mal doppelt so groß wie unter 32Bit.
    Aber solange der Speicher nicht unnötig anwächst, sollte das kein Problem sein. Ein paar Gigabyte hat doch fast jeder Rechner heutzutage.


    Lars

  • Mir ist eher zufällig aufgefallen, dass der EPG mit Abstand am meisten RAM braucht und fand es erwähnenswert.
    Ein konkretes Problem sehe ich derzeit auch nicht, zumindestens bei meinem Setup.


    Wobei man sich aber schon überlegen kann, ob es sinnvoll ist den kompletten EPG im RAM vorzuhalten.
    Ganz früher muss das eigentlich auch irgendwie anders gelöst gewesen sein. Ich erinnere mich an Zeiten, wo ich weniger RAM im VDR hatte, als heute fürs EPG drauf geht :schiel .


    Den Speicherverbrauch vom EPG müsst man eigentlich auch ganz gut "mitzählen" können. Dann wüsste man wenigstens, ob das Memory-Leak im EPG sitzt oder nicht.

    Gruss
    SHF


  • Wenn man den EPG-Scan aktiv hat, dann läuft der VDR über die komplette Kanalliste und holt auch für den noch so exotischen Sender das EPG ab.


    Hier fehlt nach wie vor mein Lieblingsfeature: Favoritenlisten für den VDR.


    Und dann bitte nurnoch EPG-Scan für die Favoriten und nicht mehr für jeden Sender in der Kanalliste.