2010-01-20 2 views
17

Ich habe einen Audio-Broadcast-Server in Python geschrieben und auf Twisted basiert. Es funktioniert gut, aber die Speicherauslastung steigt, wenn mehr Benutzer auf dem Server sind, aber die Speicherauslastung sinkt nie, wenn diese Benutzer offline gehen. Wie Sie in folgenden Abbildung sehen: alt text http://static.ez2learn.com/temp/mem_figure3.svgWie finde ich die Ursache für die zunehmende Speichernutzung eines Twisted Servers?

können Sie die Kurve der Speichernutzung sehen nach oben geht, wo die Kurve der Hörer/Radios nach oben geht, aber nach dem Höhepunkt der Zuhörer/Radios, ist die Speichernutzung nach wie vor hoch, nie sinkt.

Ich habe folgende Methode versucht, dieses Problem zu lösen:

  1. Upgrade-Verdrehte 8,2-9,0
  2. Verwenden Guppy heapy dump, aber hilft nicht bei allen
  3. Schalter Wahl Reaktor zu epoll Reaktor, gleiches Problem.
  4. Verwenden Sie Objgraph, um das Diagramm der Beziehung von Objekten zu zeichnen, aber ich kann keine Punkte daraus sehen.

ist die Umgebung, die ich für den Betrieb meiner verdrehten Server verwendet:

  • Python: 2.5.4 R254: 67916
  • OS: Linux-Version 2.6.18-164.9.1.el5PAE (mockbuild builder16.centos.org @) (gcc Version 4.1.2 20.080.704 (Red Hat 4.1.2-46))
  • Verdreht: 9.0 (unter virtualenv)

Das Abwerfen des Guppy:

siehe
Partition of a set of 116280 objects. Total size = 9552004 bytes. 
Index Count %  Size % Cumulative % Type 
    0 52874 45 4505404 47 4505404 47 str 
    1 5927 5 2231096 23 6736500 71 dict 
    2 29215 25 1099676 12 7836176 82 tuple 
    3 7503 6 510204 5 8346380 87 types.CodeType 
    4 7625 7 427000 4 8773380 92 function 
    5 672 1 292968 3 9066348 95 type 
    6 866 1 82176 1 9148524 96 list 
    7 1796 2 71840 1 9220364 97 __builtin__.weakref 
    8 1140 1 41040 0 9261404 97 __builtin__.wrapper_descriptor 
    9 2603 2 31236 0 9292640 97 int 

Wie Sie die Gesamtgröße 9552004 Bytes ist 9.1 MB, und Sie können das rss sehen von ps-Befehl gemeldet:

[[email protected] ~]$ ps -u xxxx-o pid,rss,cmd 
    PID RSS CMD 
22123 67492 twistd -y broadcast.tac -r epoll 

Der rss meines Servers ist 65,9 MB , es bedeutet, dass es 56,8 MB unsichtbaren Speicherverbrauch in meinem Server gibt, was sind sie?

Meine Fragen sind:

  1. Wie die Quelle finden Nutzungs Speicher zu erhöhen?
  2. Was sind sichtbare Speicherauslastung für Guppy?
  3. Was sind diese unsichtbaren Speicherverbrauch?
  4. Wird dies durch Speicherlecks einiger in C geschriebener Module verursacht? Wenn ja, wie kann ich das verfolgen und beheben?
  5. Wie verwaltet Python Speicher? Speicherpool? Ich denke, das könnte durch Audiodaten-Chunks verursacht werden. Es gibt also kleine Lecks im Speicherbereich des Python-Interpreters.

-Update 2010.01.20: Es ist interessant, lade ich die neueste Protokolldatei, und es zeigt, dass der Speicher von einem Moment nie zu erhöhen. Ich denke, der zugewiesene Speicherplatz ist groß genug. Hier ist die letzte Zahl. alt text http://static.ez2learn.com/temp/mem_figure4.svg

-Update 2010.01.21: Eine andere hier Figur. hum .... heben ein wenig alt text http://static.ez2learn.com/temp/mem_figure6.svg

Oops ... Noch steigen alt text http://static.ez2learn.com/temp/mem_figure7.svg

+0

Re update: Es wächst immer noch, auch wenn Ihre # Benutzer untergeht, so würde ich nicht wirklich dieses gute Verhalten nennen. Es ist schön zu wissen, dass es nicht weitergehen wird, bis der Tod durch Austausch auftritt ... – Wim

+0

Der Server läuft unter einer realen Umgebung, es ist sehr schwierig, den Grund unter diesen Bedingungen zu finden.Ich brauche etwas Zeit, um mein Programm zu vereinfachen und Simulator- und Test-Tools zu erstellen, damit ich den Server in einer testbaren Umgebung ausführen kann. Ich werde berichten, was ich sehe, sobald ich den Job erledigt habe. –

Antwort

6

Wie ich denke, ist es aufgrund Speicher Fragmentierung Problem. Das ursprüngliche Design besteht darin, Audiodaten-Blöcke in einer Liste zu halten, die alle nicht in einer festen Größe sind. Sobald die Gesamtgröße der Pufferliste die Grenze des Puffers überschreitet, werden einige Blöcke von oben in der Liste zur Begrenzung der Größe geöffnet. Es könnte wie folgt aussieht:

  1. Chunkgröße 511
  2. Chunkgröße 1040
  3. Chunkgröße 386
  4. Chunkgröße 1350
  5. ...

Die meisten von ihnen sind größer Als 256 Byte verwendet Python malloc für Chunks, die größer als 256 Byte sind, anstatt den Speicherpool zu verwenden. Und Sie können sich vorstellen, dass diese Brocken zugeordnet und freigegeben werden, was passiert wäre? Wenn beispielsweise der Chunk mit der Größe 1350 freigegeben wird, ist möglicherweise ein freier Speicherplatz von 1350 Byte im Heap vorhanden. Danach folgt eine weitere Anfrage 988, sobald malloc das Loch aufhebt, und dann gibt es ein weiteres neues kleines freies Loch der Größe 362. Nach langem Laufen gibt es immer mehr kleine Löcher in Haufen, mit anderen Worten, es gibt sie auch viele Fragmente in Haufen. Die Größe der Seite des virtuellen Speichers ist normalerweise 4 KB, diese Fragmente sind um einen großen Bereich von Heap verteilt, es macht OS diese Seiten nicht aus. Somit ist der RSS immer hoch.

Nach Änderung des Designs des Audio-Chunk-Management-Moduls meines Servers verwendet es jetzt wenig Speicher. Sie können die Figur sehen und mit der vorherigen vergleichen.

alt text http://static.ez2learn.com/temp/new_mem_figure.svg

Das neue Design Verwendung bytearray statt Liste von Strings. Es ist ein großes Stück Speicher, also gibt es keine Fragmentierung mehr.

0

Haben Sie sich Gedanken über die Verwendung von CentOS‘Alternative zu dtrace - SystemTap Ich denke, sein genannt.

Dies sollte Ihnen eine ziemlich niedrige Ebene Spur von dem, was innerhalb Ihrer * nix Prozesse passiert ....... ein Stich im Dunkeln, aber könnte Ihnen mehr Transparenz über die Intra-Prozess-Aktivität.

Interessante Frage obwohl. Ich freue mich darauf, die Antworten anderer zu sehen.

Ben

2

Es klingt wie ein Speicherleck in einem C-Modul zu mir. Valgrind ist ein gutes Werkzeug, um Speicherzuweisungsprobleme zu verfolgen. Ich weiß nicht, wie gut es mit Laufzeit-geladenen Modulen funktioniert, aber ...