DE10050684A1 - Verfahren und System zur periodischen Ablaufverfolgung für die Echtzeitgenerierung von Segmenten von Aufrufstack-Bäumen - Google Patents
Verfahren und System zur periodischen Ablaufverfolgung für die Echtzeitgenerierung von Segmenten von Aufrufstack-BäumenInfo
- Publication number
- DE10050684A1 DE10050684A1 DE10050684A DE10050684A DE10050684A1 DE 10050684 A1 DE10050684 A1 DE 10050684A1 DE 10050684 A DE10050684 A DE 10050684A DE 10050684 A DE10050684 A DE 10050684A DE 10050684 A1 DE10050684 A1 DE 10050684A1
- Authority
- DE
- Germany
- Prior art keywords
- tree data
- tree
- data structure
- routine
- program
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/30—Monitoring
- G06F11/34—Recording or statistical evaluation of computer activity, e.g. of down time, of input/output operation ; Recording or statistical evaluation of user activity, e.g. usability assessment
- G06F11/3409—Recording or statistical evaluation of computer activity, e.g. of down time, of input/output operation ; Recording or statistical evaluation of user activity, e.g. usability assessment for performance assessment
- G06F11/3419—Recording or statistical evaluation of computer activity, e.g. of down time, of input/output operation ; Recording or statistical evaluation of user activity, e.g. usability assessment for performance assessment by assessing time
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/30—Monitoring
- G06F11/34—Recording or statistical evaluation of computer activity, e.g. of down time, of input/output operation ; Recording or statistical evaluation of user activity, e.g. usability assessment
- G06F11/3466—Performance evaluation by tracing or monitoring
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F2201/00—Indexing scheme relating to error detection, to error correction, and to monitoring
- G06F2201/835—Timestamp
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F2201/00—Indexing scheme relating to error detection, to error correction, and to monitoring
- G06F2201/86—Event-based monitoring
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F2201/00—Indexing scheme relating to error detection, to error correction, and to monitoring
- G06F2201/88—Monitoring involving counting
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Computer Hardware Design (AREA)
- Quality & Reliability (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Debugging And Monitoring (AREA)
Abstract
Es wird ein Verfahren und ein System zur Profilierung eines Programms mit Hilfe der periodischen Abtastung bereitgestellt. Während der Programmausführung wird eine auf Abtastung basierende Profilierung des ausgeführten Programms durchgeführt - über eine vorgegebene Zeitspanne führt ein Profilierungsverfahren eine Protokollierungsverarbeitung für das Programm durch, danach macht das Profilierungsverfahren eine Pause und führt eine bestimmte Zeit lang keine Protokollierungsverarbeitung durch. Die Zeitspannen zur Steuerung des Profilierungsverfahrens können von einem Benutzer ausgewählt werden, und die Zeitspannen können durch temporale oder nicht-temporale Metriken gemessen werden. Das Profilierungsverfahren durchläuft diese Perioden, während derer ausgewählte Ereignisse verarbeitet werden, um ein Profil der Ausführungsflüsse in dem Programm zu erstellen. Für jede Abtastperiode wird eine Baumdatenstruktur erstellt, in der die Knoten die während der Abtastperiode ausgeführten Routinen des Programms darstellen. Dies kann durch Aufruf- und Verlassereignisse, die durch die Ausführung der Routinen verursacht werden, signalisiert werden. Wenn die Programmausführung abgeschlossen ist, werden die Baumdatenstrukturen aller Abtastperioden zu einer resultierenden Baumdatenstruktur verschmolzen.
Description
Die vorliegende Patentanmeldung ist eine teilweise Fortsetzung
der folgenden gleichzeitig anhängigen und gemeinsam
übertragenen Anmeldungen: "SYSTEM AND METHOD FOR PROVIDING
TRACE INFORMATION REDUCTION", U.S. Anmeldung mit der
Seriennummer 08/989,725, eingereicht am 12. Dezember 1997,
derzeit anhängig; "A METHOD AND APPARATUS FOR STRUCTURED
PROFILING OF DATA PROCESSING SYSTEMS AND APPLICATIONS", U.S.
Anmeldung mit der Seriennummer 09/052,329 (europäische
Patentanmeldung 99302214.4), derzeitig anhängig, eingereicht
am 31. März 1998; "A METHOD AND APPARATUS FOR STRUCTURED
MEMORY ANALYSIS OF DATA PROCESSING SYSTEMS AND APPLICATIONS",
U.S. Anmeldung mit der Seriennummer 09/052,331 (europäische
Patentanmeldung 99302225.0), derzeit anhängig, eingereicht am
31. März 1998; "METHOD AND APPARATUS FOR PROFILING PROCESSES
IN A DATA PROCESSING SYSTEM", U.S. Anmeldung mit der
Seriennummer 09/177,031, derzeit anhängig, eingereicht am 22.
Oktober 1998; "PROCESS AND SYSTEM FOR MERGING TRACE DATA FOR
PRIMARILY INTERPRETED METHODS", U.S. Anmeldung mit der
Seriennummer 09/343,439, derzeit anhängig, eingereicht am 30.
Juni 1999; und "METHOD AND SYSTEM FOR MERGING EVENT-BASED DATA
AND SAMPLED DATA INTO POSTPROCESSED TRACE OUTPUT", U.S.
Anmeldung mit der Seriennummer 09/343,438, derzeit anhängig,
eingereicht am 30. Juni 1999.
Die vorliegende Erfindung ist sachverwandt mit folgenden
Patentanmeldungen: "METHOD AND SYSTEM FOR DETECTING AND
RECOVERING FROM ERRORS IN TRACE DATA", U.S. Anmeldung mit der
Seriennummer 09/393083, eingereicht am 9. September 1999; und
"METHOD AND SYSTEM FOR PERIODIC TRACE SAMPLING FOR REAL-TIME
GENERATION OF SEGMENTS OF CALL STACK TREES AUGMENTED WITH CALL
STACK POSITION DETERMINATION", U.S. Anmeldung mit der
Seriennummer 09/418378, eingereicht am 14. Oktober 1999,
derzeit anhängig und dem gleichen Inhaber übertragen.
Die vorliegende Erfindung betrifft ein verbessertes
Datenverarbeitungssystem und speziell ein Verfähren und eine
Vorrichtung zur Leistungsoptimierung in einem
Datenverarbeitungssystem. Ganz speziell bietet die vorliegende
Erfindung ein Verfahren und eine Vorrichtung für ein
Softwareprogrammentwicklungs-Tool zur Verbesserung der
Leistungsfähigkeit eines Softwareprogramms durch Software-
Profilierung.
Bei der Analyse und Verbesserung der Leistungsfähigkeit eines
Datenverarbeitungssystems und den darauf ausgeführten
Anwendungsprogrammen ist es vorteilhaft, zu wissen, welche
Softwaremodule in einem Datenverarbeitungssystem
Systemressourcen verwenden. Eine effektive Verwaltung und
Verbesserung von Datenverarbeitungssystemen erfordert
Kenntnisse darüber, wie und wann verschiedene Systemressourcen
verwendet werden. Zur Überwachung und Prüfung eines
Datenverarbeitungssystems werden Leistungsbewertungs-Tools
eingesetzt, um den Ressourcenverbrauch bei der Ausführung
verschiedener Anwendungsprogramme auf dem
Datenverarbeitungssystem festzustellen. Ein
Leistungsbewertungs-Tool kann beispielsweise die am häufigsten
ausgeführten Module und Instruktionen in einem
Datenverarbeitungssystem identifizieren, oder es kann
erkennen, welche Module am meisten Speicherplatz zuteilen oder
die meisten E/A-Anforderungen ausführen. Als Hardware
implementierte Leistungsbewertungs-Tools können in das System
eingebaut sein oder zu einem späteren Zeitpunkt hinzugefügt
werden. Leistungsbewertungs-Tools in Softwareform sind in
Datenverarbeitungssystemen ebenfalls von Nutzen, z. B. in PC-
Systemen, die in der Regel nicht viele oder gar keine
eingebauten hardwaremäßig implementierten Leistungsbewertungs-
Tools enthalten.
Ein bekanntes Leistungsbewertungs-Tool in Softwareform ist ein
Ablaufverfolgungs-Tool. Ein Ablaufverfolgungs-Tool kann
mehrere Verfahren verwenden, um Protokolldaten zu liefern, die
Ausführungsflüsse für ein laufendes Programm erkennen lassen.
Ein Verfahren verfolgt bestimmte Abfolgen von Instruktionen,
indem bestimmte Ereignisse bei ihrem Auftreten protokolliert
werden. Dieses Verfahren wird als ereignisbasiertes
Profilierungsverfahren bezeichnet. So kann beispielsweise ein
Ablaufverfolgungs-Tool jeden Aufruf und jedes Verlassen eines
Moduls, einer Subroutine, eines Verfahrens, einer Funktion
oder einer Systemkomponente protokollieren. Alternativ kann
ein Ablaufverfolgungs-Tool aufzeichnen, wer Speicherplatz
anfordert und wieviel Speicherplatz bei jeder
Speicherzuteilungsanforderung zugeteilt wird. Typischerweise
wird für jedes derartige Ereignis eine mit einem Zeitstempel
versehene Aufzeichnung erzeugt. Zusammengehörige Paare von
Aufzeichnungen, ähnlich wie Einstiegs-/Aufstiegs-
Aufzeichnungen, werden zur Verfolgung der Ausführung
beliebiger Codesegmente, die Ein-/Ausgaben oder
Datenübertragungen starten oder beenden, aber auch zur
Verfolgung vieler anderer relevanter Ereignisse verwendet.
Um die Leistungsfähigkeit des von verschiedenen
Computerfamilien generierten Codes zu steigern, muss oft
festgestellt werden, für was der Prozessor bei der
Codeausführung Zeit aufwendet. Solche Anstrengungen werden in
der Datenverarbeitungsbranche üblicherweise als Bestimmung von
"Hot Spots" bezeichnet. Im Idealfall würde man wünschen,
solche Hot Spots auf der Instruktions- und/oder
Quellcodezeilenebene zu erkennen, um die Aufmerksamkeit auf
Bereiche zu konzentrieren, in denen Verbesserungen des Codes
die größten Vorteile bringen könnten.
Bei einem anderen Ablaufverfolgungsverfahren wird periodisch
der Ausführungsfluss eines Programms erfasst, um bestimmte
Stellen im Programm festzustellen, an denen das Programm
offensichtlich viel Zeit benötigt. Dieses Verfahren basiert
auf dem Konzept, das Anwendungsprogramm oder das
Datenverarbeitungssystem in regelmäßigen Zeitabständen zu
unterbrechen. Dies wird als Profilierung auf Abtastungsbasis
bezeichnet. Bei jeder Unterbrechung werden eine bestimmte Zeit
lang oder über eine bestimmte Anzahl von Ereignissen
Informationen aufgezeichnet. So kann beispielsweise der
Programmzähler des gerade ausgeführten Threads, eines
Prozesses der Bestandteil des größeren zu profilierenden
Programms ist, in den Intervallen protokolliert werden. Diese
Werte können nach der Verarbeitungszeit in ein
Auslastungsdiagramm und Symboltabellen für das
Datenverarbeitungssystem eingetragen werden, und aus dieser
Analyse kann ein Profil erstellt werden, aus dem zu ersehen
ist, wo die Zeit aufgewendet wird.
Die Erkennung solcher Hot Spots auf Instruktionsebene
ermöglicht es Compilerprogrammierern, wesentliche Bereiche
suboptimaler Codegenerierung zu finden, auf die sie ihre
Anstrengungen zur Steigerung der Effizienz bei der
Codegenerierung konzentrieren können. Details auf
Instruktionsebene können außerdem auch von Entwicklern
zukünftiger Systeme als Richtlinie verwendet werden. Solche
Entwickler benutzen Profilierungs-Tools, um charakteristische
Codesequenzen und/oder einzelne Instruktionen zu finden, die
einer Optimierung für die verfügbare Software für eine
bestimmte Art von Hardware bedürfen.
Die kontinuierliche ereignisbasierte Profilierung hat ihre
Grenzen. Sie nimmt zum Beispiel viel Leistung in Anspruch (ein
Ereignis pro Einstieg und pro Ausstieg), wodurch die
resultierende Leistungsbeurteilung gestört werden kann und oft
auch gestört wird. Außerdem steht dieses Verfahren nicht immer
zur Verfügung, da eine statische oder dynamische Einfügung von
Einstiegs-/Ausstiegsereignissen in den Code erforderlich ist.
Diese Einfügung von Ereignissen ist nicht immer möglich oder
oft schwierig. Wenn zum Beispiel der Quellcode nicht für den
zu instrumentierenden Code zur Verfügung steht, ist eine
ereignisbasierte Profilierung eventuell nicht möglich. Es
besteht jedoch die Möglichkeit, einen Quellcode-Interpreter so
zu instrumentieren, dass ereignisbasierte
Profilierungsinformationen gewonnen werden, ohne dass der
Quellcode geändert wird.
Andererseits ermöglicht die auf Abtastung basierende
Profilierung nur einen "flachen Blick" auf die Systemleistung,
bietet aber nicht den Vorteil geringerer Kosten und einer
geringeren Abhängigkeit von der Buchungskapazität. Ferner
lassen auf Abtastung basierende Verfahren nicht erkennen, wo
die Zeit für viele kleine und augenscheinlich nicht
miteinander zusammenhängende Funktionen aufgewendet wird, oder
für was die Zeit in Situationen, in denen kein deutlicher "Hot
Spot" erkennbar ist, benötigt wird. Ohne ein Verständnis der
Programmstruktur ist aus einem "ebenen" Profil nicht klar
ersichtlich, wie festgestellt werden kann, an welcher Stelle
Leistungsverbesserungen möglich sind.
Es wäre daher vorteilhaft, wenn es ein System gäbe, das die
Vorteile der ereignisbasierten Profilierung mit den Vorteilen
geringerer Systemstörung bei der auf Abtastung basierenden
Profilierung verbindet. Es wäre besonders vorteilhaft, wenn es
die Möglichkeit gäbe, die Profilierung ausgewählter Teile des
Datenverarbeitungssystems zu aktivieren und zu deaktivieren
und das Ergebnis dieser verschiedenen Profilierungsperioden in
einer einzigen kombinierte Darstellung aufzuzeigen.
Die vorliegende Erfindung liefert ein Verfahren und ein System
zur Profilierung eines Programms mit Hilfe einer periodischen
Abtastung zur Erstellung eines Ablaufprotokolls. Während der
Programmausführung wird eine auf Abtastung basierende
Profilierung des ausgeführten Programms durchgeführt - über
eine vorgegebene Zeitspanne führt ein Profilierungsverfahren
eine Protokollierungsverarbeitung für das Programm durch,
danach macht das Profilierungsverfahren eine Pause und führt
eine bestimmte Zeit lang keine Protokollierungsverarbeitung
durch. Die Zeitspannen zur Steuerung des
Profilierungsverfahrens können von einem Benutzer ausgewählt
werden, und die Zeitspannen können durch temporale oder nicht
temporale Metrik gemessen werden. Das Profilierungsverfahren
durchläuft diese Perioden, während derer ausgewählte
Ereignisse verarbeitet werden, um ein Profil der
Ausführungsflüsse in dem Programm zu erstellen. Für jede
Abtastperiode wird eine Baumdatenstruktur erstellt, in der die
Knoten die während der Abtastperiode ausgeführten Routinen des
Programms darstellen. Dies kann durch Ein- und
Ausstiegsereignisse, die durch die Ausführung der Routinen
verursacht werden, signalisiert werden. Wenn die
Programmausführung abgeschlossen ist, werden die
Baumdatenstrukturen aller Abtastperioden zu einer
resultierenden Baumdatenstruktur verschmolzen.
Die neuen Funktionen, die als charakteristische Merkmale der
Erfindung betrachtet werden, sind in den angefügten Ansprüchen
definiert. Die Erfindung selber sowie eine bevorzugte
Einsatzmöglichkeit und weitere Aufgaben und Vorteile der
Erfindung sind aber am besten aus der nachstehenden
detaillierten Beschreibung einer illustrativen Ausführungsform
in Verbindung mit den beigefügten Zeichnungen zu verstehen.
Die Zeichnungen haben folgenden Inhalt:
Fig. 1 zeigt ein verteiltes Datenverarbeitungssystem, in dem
die vorliegende Erfindung eingesetzt werden kann;
Die Fig. 2A-2B sind Blockdiagramme, in denen ein
Datenverarbeitungssystem dargestellt ist, in dem die
vorliegende Erfindung implementiert werden kann;
Fig. 3A ist ein Blockdiagramm, in dem die Beziehung zwischen
den Software-Komponenten in einem Computersystem, in dem die
vorliegende Erfindung implementiert ist, aufgezeigt wird.
Fig. 3B ist ein Blockdiagramm, in dem eine virtuelle Java-
Maschine gemäß einer bevorzugten Ausführungsform der
vorliegenden Erfindung dargestellt ist;
Fig. 4 ist ein Blockdiagramm, in dem die Komponenten
dargestellt sind, die zur Profilierung von Prozessen in einem
Datenverarbeitungssystem verwendet werden.
Fig. 5 ist eine Zeichnung, in der verschiedene Phasen bei der
Profilierung des aktiven Prozesses in einem Betriebssystem
dargestellt werden;
Fig. 6 ist ein Flussdiagramm, in dem von einem
Ablaufverfolgungsprogramm verwendeter Prozess zur Generierung
von Protokolldatensätzen aus den auf einem
Datenverarbeitungssystem ausgeführten Prozessen dargestellt
ist;
Fig. 7 ist ein Flussdiagramm eines Prozesses, der in einem
Systeminterrupt-Handler-Protokollanker verwendet wird;
Fig. 8 ist ein Diagramm, in dem der Aufrufstack, der Stack
Frames enthält, dargestellt ist;
Fig. 9 zeigt ein Beispiel für einen Aufrufstack;
Fig. 10A zeigt eine Programmausführungssequenz zusammen mit
dem Zustand des Aufrufstack an jedem Funktionseinstiegs- und
Funktionsausstiegspunkt.
Fig. 10B zeigt eine bestimmte zeitperiodenbasierte Abtastung
des in Fig. 10A dargestellten Ausführungsflusses;
Die Fig. 10C und 10D sind Zeitdiagramme, die ein Beispiel
der vom Profilierungs-Tool berücksichtigten Zeittypen zeigen;
Fig. 11A ist ein Diagramm, in dem eine aus der Abtastung von
Aufrufstacks generierte Baumstruktur dargestellt ist;
Fig. 11B ist ein Diagramm, das einen Ereignisbaum zeigt, der
die bei der Systemausführung beobachteten Aufrufstacks
widerspiegelt.
Fig. 12 ist eine tabellarische Darstellung eines
Aufrufstacks;
Fig. 13 ist ein Flussdiagramm, in dem ein Verfahren zur
Erstellung eines Aufrufstack-Baums mit Hilfe einer
Ablaufprotokoll-Textdatei als Eingabedatei dargestellt ist;
Fig. 14 ist ein Flussdiagramm, in dem ein Verfahren zur
dynamischen Erstellung eines Aufrufstack-Baums bei der
Abtastung während der Systemausführung dargestellt ist;
Fig. 15 zeigt einen Datensatz, der mit Hilfe der
erfindungsgemäßen Prozesse generiert wurde;
Fig. 16 zeigt eine andere Berichtsart, die erzeugt werden
kann, um die Aufrufstruktur zwischen den in Fig. 12
dargestellten Routinen aufzuzeigen;
Fig. 17 ist eine Tabelle, in der ein Bericht dargestellt ist,
der aus einer Protokolldatei generiert wurde, die sowohl
ereignisbasierte Profilierungsdaten (Methoden-Ein/Ausstiege)
und auf Abtastung basierende Profilierungsdaten (Aufrollen von
Stacks) enthält.
Fig. 18 ist eine Tabelle, in der Haupt- und Untercodes
aufgeführt sind, die dazu benutzt werden können, Module für
die Profilierung zu instrumentieren;
Fig. 19 ist ein Flussdiagramm, in dem die Verarbeitung von
Ausstiegsereignissen einschließlich der
Fehlerbehebungsverarbeitung in einem Ausführungsfluss, der
Fehler in Form entsprechungsloser Ereignisse enthalten kann,
dargestellt ist;
Fig. 20 ist ein Flussdiagramm, in dem ein Prozess zur auf
Abtastung basierten Profilierung von Ein-/Ausstiegsereignissen
unter Verwendung benutzerdefinierter Metriken zur Erzeugung
unabhängiger Aufrufstack-Baumsegmente dargestellt ist; und
Fig. 21 ist ein Flussdiagramm, in dem der Prozess dargestellt
ist, durch den ein Baum, der sogenannte Quellbaum, zu einem
zweiten Baum, dem sogenannten Zielbaum, hinzugefügt wird, um
eine Vereinigung zwischen den beiden Bäumen zu schaffen.
In den Zeichnungen, und speziell in Fig. 1, ist ein
Datenverarbeitungssystem, in dem die vorliegende Erfindung
implementiert werden kann, bildhaft dargestellt.
Das verteilte Datenverarbeitungssystem 100 ist ein Netzwerk
aus Computern, in denen die vorliegende Erfindung
implementiert werden kann. Das verteilte
Datenverarbeitungssystem 100 enthält ein Netzwerk 102, das das
Medium für Übertragungsverbindungen zwischen verschiedenen
Vorrichtungen und Computern, die im verteilten
Datenverarbeitungssystem 100 miteinander verbunden sind,
bildet. Das Netzwerk 102 kann permanente Verbindungen wie
Draht- oder Glasfaserkabel oder temporäre Verbindungen per
Telefon enthalten.
In dem dargestellten Beispiel ist ein Server 104 zusammen mit
der Speichereinheit 106 an das Netzwerk 102 angeschlossen.
Ferner sind die Clients 108, 110 und 112 an ein Netzwerk 102
angeschlossen. Diese Clients 108, 110 und 112 können zum
Beispiel PCs oder Netzwerkrechner sein. Für die Zwecke der
vorliegenden Patentanmeldung ist ein Netzwerkrechner jeder an
ein Netzwerk angeschlossene Rechner, der ein Programm oder
eine andere Anwendung von einem anderen an das Netzwerk
angeschlossenen Rechner empfängt. In dem dargestellten
Beispiel sendet der Server 104 Daten wie z. B. Boot-Dateien,
Betriebssystemabbilder und Anwendungen an die Clients 108-112.
Die Clients 108, 110 und 112 sind Clients des Servers 104. Das
verteilte Datenverarbeitungssystem 100 kann weitere Server,
Clients und sonstige Geräte enthalten, die nicht in der
Zeichnung dargestellt sind. In dem abgebildeten Beispiel ist
das verteilte Datenverarbeitungssystem 100 das Internet, wobei
das Netzwerk 102 eine weltweite Sammlung von Netzwerken und
Gateways darstellt, die zur Kommunikation untereinander die
TCP/IP-Protokolle verwenden. Im Zentrum des Internet befindet
sich ein Backbone von schnellen Datenübertragungsleitungen
zwischen den Hauptknoten oder Host-Computern, die aus
tausenden Computersystemen von kommerziellen Betreibern, von
Regierungsstellen, von Ausbildungsstätten und sonstigen
Betreibern bestehen, die Daten und Nachrichten durch das Netz
leiten. Ein verteiltes Datenverarbeitungssystem 100 kann
selbstverständlich aus einer Anzahl verschiedener
Netzwerktypen wie z. B. Intranet oder LAN bestehen.
Fig. 1 ist als Beispiel zu verstehen, nicht als Einschränkung
der Netzwerkarchitektur für die erfindungsgemäßen Prozesse.
In Fig. 2A ist ein Blockdiagramm eines
Datenverarbeitungssystems dargestellt, das im Rahmen der
Erfindung als Server wie z. B. Server 104 in Fig. 1
implementiert werden kann. Das Datenverarbeitungssystem 200
kann ein symmetrisches Multiprozessorsystem (SMP) mit mehreren
an den Systembus 206 angeschlossenen Prozessoren 202 und 204
sein. Alternativ kann auf ein Einprozessorsystem verwendet
werden. An den Systembus 206 ist auch ein
Speichercontroller/Cache 208 angeschlossen, der eine
Schnittstelle zum lokalen Speicher 209 bildet. Die E/A-
Busbrücke 210 ist an den Systembus 206 angeschlossen und
bildet eine Schnittstelle zum E/A-Bus 212. Der
Speichercontroller/Cache 208 und die E/A-Busbrücke 210 können
so implementiert sein wie in der Zeichnung.
Die an den E/A-Bus 212 angeschlossene PCI-Busbrücke 214 bildet
eine Schnittstelle zum lokalen PCI-Bus 216. An den lokalen
PCI-Bus 216 kann ein Modem 218 angeschlossen sein. Typische
PCI-Bus-Implementierungen unterstützen vier PCI-
Erweitungssteckplätze. Die Übertragungsverbindungen zu den
Netzwerkrechnern 108-112 in Fig. 1 können über das Modem 218
und die Netzwerkkarte 220, als Erweiterungskarte an den
lokalen PCI-Bus 216 angeschlossen ist, hergestellt werden.
Weitere PCI-Busbrücken 222 und 224 bilden Schnittstellen für
weitere PCI-Busse 226 und 228, von denen zusätzliche Modems
oder Netzwerkkarten unterstützt werden können. Auf diese Weise
ermöglicht der Server 200 Verbindungen zu mehreren
Netzwerkrechnern. Wie abgebildet können auch ein Grafikadapter
230 mit Speicherabbild und eine Festplatte 232 entweder direkt
oder indirekt an den E/A-Bus 212 angeschlossen sein.
Der durchschnittliche Fachmann weiß, daß die in Fig. 2A
dargestellte Hardware auch anders aussehen kann. So können zum
Beispiel zusätzlich zu der dargestellten Hardware oder
anstelle der dargestellten Hardware andere Peripheriegeräte
wie ein optisches Plattenlaufwerk oder ähnliches verwendet
werden. Das abgebildete Beispiel soll keine Einschränkungen
der Architektur für die vorliegende Erfindung implizieren.
Das in Fig. 2A abgebildete Datenverarbeitungssystem kann
beispielsweise ein IBM RISC/System 6000, ein Produkt der
International Business Machines Corporation in Armonk, New
York, sein, auf dem das Betriebssystem AIX (Advanced
Interactive Executive) läuft.
In Fig. 2B ist ein Blockdiagramm eines
Datenverarbeitungssystems, in dem die vorliegende Erfindung
implementiert werden kann, zu sehen. Das
Datenverarbeitungssystem 250 ist ein Beispiel für einen
Client-Computer. Das Datenverarbeitungssystem 250 verwendet
eine PCI-Lokalbus-Architektur. Statt des abgebildeten PCI-Bus
kann auch eine andere Busarchitektur wie Micro Channel oder
ISA verwendet werden. Der Prozessor 252 und der Hauptspeicher
254 sind über die PCI-Brücke 258 an den PCI-Lokalbus 256
angeschlossen. Die PCI-Brücke 258 kann auch einen integrierten
Speichercontroller und Cache-Speicher für den Prozessor 252
enthalten. Weitere Verbindungen zum PCI-Lokalbus 256 können
über Komponentendirektverbindungen oder Erweiterungskarten
hergestellt werden. In dem dargestellten Beispiel sind der
LAN-Adapter 260, der SCSI-Hostbusadapter 262 und die
Erweiterungsbusschnittstelle 264 durch eine
Komponentendirektverbindung an den PCI-Lokalbus 256
angeschlossen. Die Soundkarte 266, die Grafikkarte 268 und der
Audio/Video-Adapter (A/V) 269 hingegen sind durch
Erweiterungskarten in den Steckplätzen an den PCI-Lokalbus 266
angeschlossen. Die Erweiterungsbusschnittstelle 264 bietet
einen Anschluss für einen Tastatur- und Mausadapter 270, ein
Modem 272 und einen Erweiterungsspeicher 274. Über den SCSI-
Hostbusadapter 262 sind in diesem Beispiel ein
Festplattenlaufwerk 276, ein Bandlaufwerk 278 und ein CD-ROM-
Laufwerk 280 angeschlossen. Typische PCI-Lokalbus-
Implementierungen unterstützen drei oder vier PCI-
Erweitungssteckplätze.
Auf dem Prozessor 252 läuft ein Betriebssystem, das
verschiedene Komponenten im Datenverarbeitungssystem 250 in
Fig. 2B koordiniert und steuert. Das Betriebssystem kann ein
handelsübliches Betriebssystem wie Java-OS For BusinessÔ oder
OS/2Ô von der International Business Machines CorporationÔ
sein. JavaOS wird von einem Server in einem Netzwerk auf einen
Netzwerk-Client geladen und unterstützt Java-Programme und
Applets. Eine Eigenschaft von JavaOS, die günstig für die
Ablaufverfolgung mittels Stack-Aufrollung wie unten
beschrieben sind, ist, dass JavaOS keine Seitenauslagerung und
keinen virtuellen Speicher unterstützt. Ein objektorientiertes
Programmiersystem wie Java kann in Verbindung mit dem
Betriebssystem laufen und Betriebssystemaufrufe von Java-
Programmen oder Anwendungen, die auf dem
Datenverarbeitungssystem 250 ausgeführt werden, ermöglichen.
Instruktionen für das Betriebssystem, das objektorentierte
Betriebssystem und Anwendungen oder Programme befinden sich in
Speichervorrichtungen wie z. B. auf dem Festplattenlaufwerk 276
und können zur Ausführung durch den Prozessor 252 in den
Hauptspeicher 254 geladen werden. Wenn das
Datenverarbeitungssystem 250 als Netzwerk-Client verwendet
wird, ist oft kein Festplattenlaufwerk vorhanden und der
Speicher begrenzt.
Der durchschnittliche Fachmann weiß, daß die in Fig. 2B
dargestellte Hardware je nach Implementierung unterschiedlich
aussehen kann. So können zum Beispiel zusätzlich zu der in
Fig. 2B dargestellten Hardware oder anstelle der in Fig. 2B
dargestellten Hardware andere Peripheriegeräte wie optische
Plattenlaufwerke oder ähnliches verwendet werden. Das
abgebildete Beispiel soll keine Einschränkungen der
Architektur für die vorliegende Erfindung implizieren. So
können die erfindungsgemäßen Prozesse beispielsweise auf ein
Multiprozessor-Datenverarbeitungssystem angewendet werden.
Die vorliegende Erfindung bietet einen Prozess und ein System
zur Profilierung von Software-Anwendungen. Sie kann auf
verschiedenen Computerplattformen und Betriebssystemen
eingesetzt werden, u. a. in einer Java-Laufzeitumgebung. Die
vorliegende Erfindung kann daher in Verbindung mit einer JVM
(Java Virtual Machine) eingesetzt werden und sich dennoch
innerhalb der Grenzen einer JVM nach den Spezifikationen des
Java-Standards bewegen. Um einen Kontext für die vorliegende
Erfindung herzustellen, wird hier zum Teil auch die
Funktionsweise einer JVM nach den Java-Spezifikationen
beschrieben.
Fig. 3A ist ein Blockdiagramm, in dem die Beziehung zwischen
den Software-Komponenten in einem Computersystem, in dem die
vorliegende Erfindung implementiert ist, aufgezeigt wird. Das
Java-basierte System 300 enthält das plattformspezifische
Betriebssystem 302, das Hardware- und Systemunterstützung für
die auf einer bestimmten Hardware-Plattform laufende Software
bietet. JVM 304 ist ein Anwendungsprogramm, das in Verbindung
mit dem Betriebssystem ausgeführt werden kann. Die JVM 304
bildet eine Java-Laufzeitumgebung mit der Möglichkeit, Java-
Anwendung oder Applet 306, d. h. ein Programm, ein Servlet oder
eine Softwarekomponente in der Programmiersprache Java,
auszuführen. Das Computersystem, in dem JVM 304 läuft, kann
ähnlich sein wie das Datenverarbeitungssystem 200 oder das
Computersystem 100, die oben beschrieben wurden. JVM 304 kann
aber auch auf einer dedizierten Hardware auf einem sogenannten
Java-Chip, Java-on-Silicon oder Java-Prozessor mit
eingebettetem picoJava-Kern implementiert sein.
Im Zentrum einer Java-Laufzeitumgebung steht die JVM, die alle
Aspekte der Java-Umgebung einschließlich Architektur,
Sicherheitsfunktionen, Mobilität zwischen Netzwerken und
Plattformunabhängigkeit unterstützt.
Die JVM ist ein virtueller Computer, d. h. ein Computer, der
abstrakt spezifiziert ist. Die Spezifikation definiert
bestimmte Merkmale, die jede JVM implementieren muss, wobei je
nach Plattform, auf der die JVM laufen soll, bestimmte
Auswahlmöglichkeiten bestehen. So müssen alle JVMs Java-
Bytecode ausführen, und sie können verschiedene Verfahren
verwenden, um die durch die Bytecodes repräsentierten
Instruktionen auszuführen. Eine JVM kann komplett als Software
oder teilweise als Hardware implementiert werden. Durch diese
Flexibilität können verschiedene JVMs für Großrechern und PDAs
entwickelt werden.
Die JVM ist der Name einer virtuellen Computerkomponente, die
Java-Programme tatsächlich ausführt. Java-Programme werden
nicht direkt von der CPU ausgeführt, sondern von der JVM, die
ihrerseits eine auf dem Prozessor laufende Software ist. Die
JVM ermöglicht die Ausführung von Java-Programmen auf einer
anderen Plattform als derjenigen, für die der Code kompiliert
worden ist. Java-Programme werden für die JVM kompiliert. Auf
diese Weise kann Java Anwendungen für viele verschiedene Arten
von Datenverarbeitungsstemen unterstützen, die verschiedene
CPUs und Betriebssystemarchitekturen aufweisen können. Damit
eine Java-Anwendung auf verschiedenen Arten von
Datenverarbeitungssystemen ausgeführt werden kann, generiert
ein Compiler typischerweise ein architekturneutrales
Dateiformat - der kompilierte Code kann auf vielen Prozessoren
ausgeführt werden, sofern das Java-Laufzeitsystem vorhanden
ist. Der Java-Compiler generiert Bytecode-Instruktionen, die
nicht für eine bestimmte Computerarchitektur spezifisch sind.
Ein Bytecode ist ein maschinenunabhängiger Code, der vom Java-
Compiler generiert und von einem Java-Interpreter ausgeführt
wird. Ein Java-Interpreter ist ein Teil der JVM, der
abwechselnd einen oder mehrere Bytecodes decodiert und
interpretiert. Diese Bytecode-Instruktionen sind so
konzipiert, dass sie auf jedem Computer einfach zu
interpretieren und leicht auf der Stelle in nativen
Maschinencode umgewandelt werden können. Bytecodes können
durch einen JIT-Compiler (Just-in-Time Compiler) in nativen
Code umgewandelt werden.
Eine JVM muss Klassendateien laden und die Bytecodes darin
ausführen. Die JVM enthält einen Klassenlader, der
Klassendateien von einer Anwendung und die von der Anwendung
benötigten Klassendateien von den Java-
Anwendungsprogrammierschnittstellen (APIs) lädt. Die
Ausführungsmaschine, die den Bytecode ausführt, kann je nach
Plattform und Implementierung unterschiedlich gestaltet sein.
Eine Art software-basierter Ausführungsmaschine ist ein JIT-
Compiler. Bei dieser Art der Ausführung wird der Bytecode
eines Verfahrens in nativen Maschinencode kompiliert, wenn
bestimmte Kriterien für das Jitting eines Verfahrens erfüllt
sind. Der native Maschinencode für das Verfahren kommt dann in
den Cache und wird beim nächsten Aufruf des Verfahrens
verwendet. Die Ausführungsmaschine kann auch als Hardware
implementiert und in einen Chip integriert werden, so dass die
Java-Bytecodes nativ ausgeführt werden. Üblicherweise
interpretieren JVMs den Bytecode, sie können aber auch andere
Verfahren wie die JIT-Kompilierung verwenden, um Bytecodes
auszuführen.
Die Interpretation des Codes bietet einen zusätzlichen
Vorteil. Anstelle des Java-Quellcodes kann der Interpreter
instrumentiert werden. Protokolldaten können über ausgewählte
Ereignisse und Timer durch den instrumentierten Interpreter
generiert werden, ohne dass der Quellcode modifiziert wird.
Die Instrumentation der Profilierung wird weiter unten
ausführlicher beschrieben.
Wenn eine Anwendung auf einer JVM ausgeführt wird, die in Form
von Software auf einem plattformspezifischen Betriebssystem
implementiert ist, kann eine Java-Anwendung durch Aufruf
nativer Verfahren mit dem Host-Betriebssystem interagieren.
Ein Java-Verfahren ist in der Java-Sprache geschrieben, in
Bytecodes kompiliert und in Klassendateien gespeichert. Ein
natives Verfahren ist in einer anderen Sprache geschrieben und
in den nativen Maschinencode eines bestimmten Prozessors
kompiliert. Native Verfahren werden in einer dynamisch
verknüpften Bibliothek (dynamically linked library - DLL)
gespeichert, deren exakte Form plattformspezifisch ist.
Fig. 3B ist ein Blockdiagramm einer JVA gemäß einer
bevorzugten Ausführungsform der vorliegenden Erfindung. JVM
350 enthält ein Klassenlader-Subsystem 352, bei dem es sich um
einen Mechanismus zum Laden von Typen wie Klassen und
Schnittstellen mit vollständig qualifizierten Namen handelt.
Die JVM 350 enthält auch Laufzeit-Datenbereiche 354, die
Ausführungsmaschine 356, die Schnittstelle 358 für native
Verfahren und die Speicherverwaltung 374. Die
Ausführungsmaschine 356 ist ein Mechanismus zum Ausführen von
Instruktionen, die in den vom Klassenlader-Subsystem 352
geladenen Klassenmethoden enthalten sind. Die
Ausführungsmaschine 356 kann beispielsweise ein Java-
Interpreter 362 oder ein JIT-Compiler 360 sein. Die
Schnittstelle 358 für native Verfahren ermöglicht den Zugriff
auf Ressourcen im zugrunde liegenden Betriebssystem. Die
Schnittstelle 358 für native Verfahren kann beispielsweise
eine native Java-Schnittstelle sein.
Die Laufzeitdatenbereiche 354 enthalten Stacks 364 für native
Verfahren, Java-Stacks 366, PC-Register 368, einen
Methodenbereich 370 und einen Heap 372. Diese verschiedenen
Datenbereiche repräsentieren die Speicherorganisation, die von
der JVM 350 benötigt wird, um ein Programm auszuführen.
Die Java-Stacks 366 dienen zur Speicherung des Status von
Java-Verfahrensaufrufen. Wenn ein neuer Thread angefangen
wird, erzeugt die JVM einen neuen Java-Stack für den Thread.
Die JVM führt nur zwei Operationen direkt an Java-Stacks aus:
das Schieben und Wegnehmen von Frames. Der Java-Stack eines
Threads speichert den Status von Java-Verfahrensaufrufen für
diesen Thread. Der Status eines Java-Verfahrensaufrufs umfasst
dessen lokale Variablen, die Parameter, mit denen er
aufgerufen wurde, ggf. seinen Rückkehrwert sowie
Zwischenrechnungen. Java-Stacks sind aus Stack Frames
zusammengesetzt. Ein Stack Frame enthält den Status eines
einzigen Java-Verfahrensaufrufs. Wenn ein Thread ein Verfahren
aufruft, schiebt die JVM einen neuen Frame auf den Java-Stack
des Threads. Wenn das Verfahren abgeschlossen ist, nimmt die
JVM den Rahmen für dieses Verfahren weg und löscht ihn. Die
JVM besitzt keine Register zur Speicherung von Zwischenwerten;
jede Java-Instruktion, die einen Zwischenwert benötigt oder
erzeugt, verwendet den Stack zur Speicherung der
Zwischenwerte. Dadurch ist der Java-Instruktionssatz für
verschiedene Plattformarchitekturen exakt definiert.
Die PC-Register 368 enthalten Informationen darüber, welche
Instruktion als nächste auszuführen ist. Jeder Thread, von dem
eine Instanz gebildet wird, erhält sein eigenes PC-Register
(Programmzähler) und seinen eigenen Java-Stack. Wenn der
Thread ein JVM-Verfahren ausführt, gibt der Wert im PC-
Register an, welche Instruktion als nächste auszuführen ist.
Wenn der Thread ein natives Verfahren ausführt, ist der Inhalt
des PC-Registers undefiniert.
Die Stacks 364 für native Verfahren speichern den Status von
Aufrufen nativer Verfahren. Der Status von Aufrufen nativer
Verfahren wird auf eine von der Implementierung abhängigen
Weise in Stacks für native Verfahren, Registern oder anderen
von der Implementierung abhängigen Speicherbereichen
gespeichert. In einigen JVM-Implementierungen sind Stacks 364
für native Verfahren und Java-Stacks 366 kombiniert.
Der Verfahrensbereich 370 enthält Klassendaten, während Heap
372 alle Objekte, von denen eine Instanz gebildet wurde,
enthält. In den JVM-Spezifikation sind Datentypen und
Operationen streng definiert. Die meisten JVMs entscheiden
sich für einen Verfahrensbereich und einen Heap, die beide von
allen in der JVM laufenden Threads gemeinsam benutzt werden.
Wenn eine JVM eine Klassendatei lädt, analysiert sie
Informationen über einen Typ aus den in der Klassendatei
enthaltenen Binärdaten. Diese Typinformationen stellt sie in
den Verfahrensbereich. Jedesmal, wenn eine Klasseninstanz oder
Matrix erzeugt wird, wird Speicher von Heap 372 für das neue
Objekt zugeteilt. Die JVM 350 enthält eine Instruktion, die
Speicherplatz im Speicher für Heap 372 zuteilt, sie enthält
aber keine Instruktion zum Freigeben dieses Speicherbereichs.
Die Speicherverwaltung 374 in dem dargestellten Beispiel
verwaltet den Speicherplatz in dem Speicher, der Heap 370
zugeteilt ist. Die Speicherverwaltung 374 kann einen
"Müllsammler" enthalten, der automatisch den Speicher
zurückfordert, der von Objekten benutzt wird, auf die es
keinen Verweis mehr gibt. Außerdem kann ein "Müllsammler" auch
Objekte verschieben, um die Fragmentierung des Heap zu
reduzieren.
Die Prozesse in den folgenden Figuren geben einen globalen
Überblick über die zahlreichen Prozesse, die in der Erfindung
verwendet werden: Prozesse, die ereignisbasierte
Profilierungsinformationen generieren; Prozesse, die auf
Abtastung basierende Profilierungsinformationen generieren;
Prozesse, die die Profilierungsinformationen zur Erzeugung
nützlicherer Informationen wie Darstellungen von Aufrufstack-
Bäumen, die in Profilberichte geschrieben werden, verwenden;
und Prozesse, die die Profilberichte für den Benutzer des
Profilierungsdienstprogramms generieren.
Fig. 4 ist ein Blockdiagramm, in dem die Komponenten
dargestellt sind, die zur Profilierung von Prozessen in einem
Datenverarbeitungssystem verwendet werden. Zur Profilierung
der Prozesse 402 wird ein Ablaufverfolgungsprogramm 400
verwendet. Das Ablaufverfolgungsprogramm 400 kann zur
Aufzeichnung von Daten bei der Ausführung eines Ankers
verwendet werden. Bei diesem handelt es sich um einen
speziellen Code an einer bestimmten Stelle in einer Routine
oder in einem Programm, wo andere Routinen ansetzen können.
Ablaufverfolgungsanker werden typischerweise für die
Fehlersuche, für die Leistungsanalyse oder zur Erweiterung der
Funktionalität eingefügt. Diese Ablaufverfolgungsanker werden
dazu benutzt, Protokolldaten an das Ablaufverfolgungsprogramm
400 zu senden, das die Protokolldaten im Puffer 404 speichert.
Die Protokolldaten im Puffer 404 können anschließend zur
Weiterverarbeitung in einer Datei gespeichert oder in Echtzeit
verarbeitet werden.
Bei Java-Betriebssystemen benutzt die vorliegende Erfindung
Ablaufverfolgungsanker, die helfen, die Verfahren zu
identifizieren, die in den Prozessen 402 verwendet werden. Da
Klassen geladen und entladen werden können, können diese
Änderungen ebenfalls mit Hilfe von Protokolldaten
identifiziert werden. Dies ist vor allem bei Netzwerk-Client-
Datenverarbeitungssystemen wie den unter JavaOS laufenden
Systemen relevant, da Klassen und JIT-Verfahren möglicherweise
wegen des beschränkten Speicherplatzes und der Rolle als
Netzwerk-Client häufiger geladen und entladen werden. Es sei
darauf hingewiesen, dass Informationen über das Laden und
Entladen von Klassen auch in eingebetteten
Anwendungsumgebungen, in denen meist nur beschränkt
Speicherplatz zur Verfügung steht, relevant sind.
In Fig. 5 sind verschiedene Phasen bei Profilierung der in
einem Betriebssystem aktiven Prozesse in einem Diagramm
dargestellt. Im Rahmen der Speichermöglichkeiten kann die
generierte Protokollausgabe so lang und so detailliert sein
wie der Analysierende es für den Zweck der Profilierung eines
bestimmten Programms für erforderlich hält.
In einer Initialisierungsphase 500 wird der Status der Client-
Maschine zu Beginn der Protokollierung erfasst. Diese
Protokollinitialisierungsdaten enthalten Protokolldatensätze,
die alle vorhandenen Threads, alle geladenen Klassen und alle
Verfahren für die geladenen Klassen identifizieren. Von den
von Ankern erfassten Protokolldaten werden Datensätze
geschrieben, die über Umschaltungen zwischen Threads,
Interrupts und das Laden und Entladen von Klassen und
gejitteten Verfahren informieren. Für jede geladene Klasse
gibt es Protokolldatensätze, in denen der Name der Klasse und
ihre Verfahren angegeben sind. In dem dargestellten Beispiel
werden vier Byte lange IDs als Kennungen für Threads, Klassen
und Verfahren verwendet. Diese IDs werden Namen zugeordnet,
die in den Datensätzen ausgegeben worden sind. Es wird ein
Datensatz geschrieben, der signalisiert, wenn die Erfassung
aller Startdaten abgeschlossen ist.
Dann werden in der Profilierungsphase 502 Protokolldatensätze
in einen Protokollpuffer oder in eine Protokolldatei
geschrieben. In der vorliegenden Erfindung kann ein
Protokollpuffer eine Kombination von Satztypen enthalten, z. B.
Sätze, die von einem Ablaufverfolgungsanker stammen, der als
Reaktion auf eine bestimmte Art von Ereignis, z. B. einen
Aufruf oder die Beendigung eines Verfahrens, ausgeführt wird,
und Sätze, die von einer Stackdurchlauffunktion stammen, die
als Reaktion auf einen Timer-Interrupt ausgeführt werden, z. B.
ein Stack-Aufrollsatz, der auch als Aufrufstack-Datensatz
bezeichnet wird.
In der Profilierungsphase können beispielsweise folgende
Prozesse vorkommen, falls der Benutzer des
Profilierungsdienstprogramms auf Abtastung basierende
Profilierungsinformationen angefordert hat. Jedesmal, wenn
eine bestimmte Art von Timer-Interrupt auftritt, wird ein
Protokolldatensatz geschrieben, der den Systemprogrammzähler
angibt. Dieser Systemprogrammzähler kann zur Identifikation
der unterbrochenen Routine verwendet werden. In dem
dargestellten Beispiel wird ein Timer-Interrupt dazu benutzt,
die Erfassung von Protokolldaten einzuleiten.
Selbstverständlich können nicht nur Timer-Interrupts verwendet
werden, sondern auch andere Arten von Interrupts. Es können
auch Interrupts verwendet werden, die auf einem programmierten
Leistungsüberwachungsereignis oder anderen Arten periodisch
wiederkehrender Ereignisse basieren.
In der Nachverarbeitungsphase 504 werden die im
Protokollpuffer gesammelten Daten zur Nachverarbeitung an eine
Protokolldatei gesendet. In einer Konfiguration kann die Datei
an einen Server gesendet werden, der das Profil für die
Prozesse auf der Client-Maschine ermittelt. Selbstverständlich
kann die Nachverarbeitung, je nachdem, wieviel
Systemressourcen verfügbar sind, auch auf der Client-Maschine
stattfinden. In der Nachverarbeitungsphase 504 können B-Bäume
und/oder Hash-Tabellen verwendet werden, um die Namen, die den
Datensätzen in der zu verarbeitenden Protokolldatei zugeordnet
sind, zu verwalten. Eine Hash-Tabelle verwendet die Hashing-
Technik, um eine Kennung oder einen Schlüssel, die für einen
Benutzer eine Bedeutung tragen, in einen Wert für die Position
der entsprechenden Daten in der Tabelle umzuwandeln. Während
der Verarbeitung von Protokolldatensätzen werden die B-Bäume
und/oder Hash-Tabellen aktualisiert, so dass sie den aktuellen
Status der Client-Maschine einschließlich des neu geladenen
JIT-Codes oder des entladenen Codes wiedergeben. Außerdem
werden in der Nachverarbeitungsphase 504 alle
Protokolldatensätze der Reihe nach verarbeitet. Sobald der
Indikator, dass alle Startinformationen verarbeitet worden
sind, gefunden wird, werden die Protokolldatensätze von
Ablaufverfolgungsankern und die Protokolldatensätze von Timer-
Interrupts verarbeitet. Timer-Interrupt-Informationen aus den
Timer-Interrupt-Datensätzen werden anhand der vorhandenen
Hash-Tabellen aufgelöst. Außerdem identifizieren diese
Informationen den Thread und die Funktion, die ausgeführt
werden. Die Daten werden in Hash-Tabellen gespeichert, wobei
ein Zählerwert die Anzahl der Ticks für jede Art der
Betrachtung der Daten zählt. Wenn alle Protokolldatensätze
verarbeitet worden sind, werden die Informationen für die
Ausgabe in Form eines Berichts formatiert.
Alternativ können die Protokollinformationen an Ort und Stelle
verarbeitet werden, so dass die Protokolldatenstrukturen
während der Profilierungsphase verwaltet werden. Mit anderen
Worten: Während eine Profilierungsfunktion wie ein Timer-
Interrupt ausgeführt wird, anstatt dass Protokolldatensätze in
einen Puffer oder in eine Datei geschrieben werden (oder
zusätzlich dazu), wird die in den Protokolldatensätzen
enthaltene Information verarbeitet, um geeignete
Datenstrukturen zu erstellen und zu verwalten.
Zum Beispiel könnte während der Verarbeitung eines Timer-
Interrupts in der Profilierungsphase festgestellt werden, ob
der unterbrochene Code gerade vom Java-Interpreter
interpretiert wird. Wenn der unterbrochene Code tatsächlich
gerade interpretiert wird, kann die Verfahrenskennung des
interpretierten Verfahrens in den Protokolldatensatz
geschrieben werden. Außerdem kann der Name des Verfahrens
ermittelt und in den entsprechenden B-Baum geschrieben werden.
Nach Abschluss der Profilierungsphase können die
Datenstrukturen alle zur Erstellung eines Profilberichts
erforderlichen Informationen enthalten, ohne dass die
Protokolldatei einer Nachverarbeitung bedarf.
Fig. 6 ist ein Flussdiagramm, in dem ein von einem
Ablaufverfolgungsprogramm verwendeter Prozess zur Generierung
von Protokolldatensätzen aus den auf einem
Datenverarbeitungssystem ausgeführten Prozessen dargestellt
ist. Fig. 6 zeigt weitere Details über die Generierung von
Protokolldatensätzen, auf die im Zusammenhang mit Fig. 5
nicht eingegangen wurde.
Protokolldatensätze können durch Ausführung kleiner
Codestücke, den sogenannten "Ankern" erzeugt werden. Anker
können auf verschiedene Weise in den von Prozessen
ausgeführten Code eingefügt werden, z. B. statisch (Quellcode)
oder dynamisch (durch Modifikation eines geladenen
ausführbaren Codes). Dieser Prozess wird angewendet, nachdem
bereits Anker in den relevanten Prozess oder die relevanten
Prozesse eingefügt worden sind. Der Prozess beginnt damit,
dass ein Puffer wie Puffer 404 in Fig. 4 zugeteilt wird
(Schritt 600). Anschließend werden in dem dargestellten
Beispiel Ablaufverfolgungsanker aktiviert (Schritt 602), und
die Protokollierung der Prozesse im System beginnt (Schritt
604). Von den interessierenden Prozessen werden Protokolldaten
empfangen (Schritt 606). Diese Art der Protokollierung kann in
den Phasen 500 und/oder 502 erfolgen. Diese Protokolldaten
werden als Protokolldatensätze im Puffer gespeichert (Schritt
608). Nun wird festgestellt, ob die Protokollierung beendet
ist (Schritt 610). Die Protokollierung endet, wenn der
Protokollpuffer voll ist, oder wenn der Benutzer die
Protokollierung durch einen Befehl beendet und anfordert, dass
der Pufferinhalt an eine Datei gesendet wird. Ist die
Protokollierung noch nicht abgeschlossen, kehrt der Prozess zu
dem oben beschriebenen Schritt 606 zurück.
Andernfalls, wenn die Protokollierung abgeschlossen ist, wird
der Pufferinhalt zur Nachverarbeitung an eine Datei gesendet
(Schritt 612). In der Nachverarbeitung wird dann ein Bericht
erstellt (Schritt 614), und danach endet der Prozess.
In dem beschriebenen Beispiel findet eine Nachverarbeitung
statt, um die Protokolldatensätze zu analysieren; die
erfindungsgemäßen Prozesse können je nach Implementierung aber
auch zur Verarbeitung von Protokollinformationen in Echtzeit
verwendet werden.
In Fig. 7 ist in einem Flussdiagramm ein Prozess dargestellt,
der während eines Interrupt-Handler-Ablaufverfolgungsankers
verwendet werden kann.
Der Prozess beginnt damit, dass ein Programmzähler abgelesen
wird (Schritt 700). Typischerweise steht der Programmzähler in
einem der gespeicherten Programm-Stack-Bereiche zur Verfügung.
Anschließend wird festgestellt, ob es sich bei dem
unterbrochenen Code um interpretierten Code handelt (Schritt
702). Diese Feststellung kann getroffen werden, indem
festgestellt wird, ob der Programmzähler in einem
Adressbereich für den zur Interpretation von Bytecodes
verwendeten Interpreter steht. Wenn es sich bei dem
unterbrochenen Code um einen interpretierten Code handelt,
wird für den interpretierten Code eine Verfahrensblockadresse
ermittelt. Dann wird ein Protokolldatensatz geschrieben
(Schritt 706). Der Protokolldatensatz wird geschrieben, indem
die Protokollinformation an ein Ablaufverfolgungsprogramm wie
das Ablaufverfolgungsprogramm 400 gesendet wird, das im
dargestellten Beispiel Protokolldatensätze zur
Nachverarbeitung generiert. Dieser Protokolldatensatz wird als
Interrupt-Datensatz oder Interrupt-Anker beschrieben.
Diese Art der Protokollierung kann während der Phase 502
durchgeführt werden. Alternativ kann ein entsprechender
Prozess, d. h. die Feststellung, ob es sich bei dem
unterbrochenen Code um einen interpretierten Code handelt, bei
der Nachverarbeitung einer Protokolldatei stattfinden.
Zur Gewinnung von auf Abtastung basierenden
Profilierungsinformationen kann eine Gruppe von Prozessen
verwendet werden. Bei der Ausführung von Anwendungen können
diese periodisch unterbrochen werden, um Informationen über
die aktuelle Laufzeitumgebung zu gewinnen. Diese Informationen
können zur Nachverarbeitung in einen Puffer oder eine Datei
geschrieben werden, oder sie können sofort an Ort und Stelle
zu Datenstrukturen verarbeitet werden, die eine fortlaufende
Geschichte der Laufzeitumgebung wiedergeben. In Fig. 8 und
Fig. 9 wird die auf Abtastung basierende Profilierung
ausführlicher beschrieben.
Ein auf Abtastung basierendes Profilierungsdienstprogramm kann
Informationen aus dem Stack eines unterbrochenen Threads
gewinnen. Der Thread wird durch einen Software-Timer-Interrupt
wie er in vielen Betriebssystemen zur Verfügung steht,
unterbrochen. Der Benutzer der Protokollierungseinrichtung
wählt entweder die Programmzähleroption oder die Stack-
Aufschlüsselungsoption. Dies kann dadurch erreicht werden, dass
ein Hauptcode oder ein anderer Hauptcode aktiviert wird wie
weiter unten beschrieben. Dieser Timer-Interrupt wird zur
Abtastung von Informationen von einem Aufrufstack verwendet.
Indem der Aufrufstack von hinten aufgerollt wird, kann ein
kompletter Aufrufstack für die Analyse abgefragt werden. Das
"Durchlaufen" eines Stacks kann auch als "Aufrollen" des
Stacks beschrieben werden. Diese Begriffe sind Metaphern für
den Prozess. Der Prozess kann insofern als "Durchlaufen"
beschrieben werden, als der Prozess die Stack Frames Schritt
für Schritt oder Frame für Frame abrufen und verarbeiten muss.
Der Prozess kann insofern auch als "Aufrollen" bezeichnet
werden, als er die Stack Frames, die auf einander verweisen,
abrufen und verarbeiten muss, und diese Zeiger und ihre
Informationen müssen durch viele Verweisaufhebungen hindurch
"abgerollt" werden.
Das Abrollen des Stacks folgt der Reihenfolge der
Funktionen/Verfahrensaufrufe zum Zeitpunkt der Unterbrechung.
Ein Aufrufstack ist eine geordnete Auflistung von Routinen
plus der Offsets in den Routinen (d. h. Module, Funktionen,
Verfahren usw.), deren Abarbeitung bei der Ausführung eines
Programms begonnen wurde. Wenn beispielsweise Routine A
Routine B aufruft und Routine B dann Routine C aufruft,
während der Prozessor Instruktionen in Routine C aufruft,
lautet der Aufrufstack ABC. Wenn die Steuerung von Routine C
zu Routine B zurückgegeben wird, lautet der Aufrufstack AB.
Zur kompakteren Darstellung und einfacheren Interpretation in
einem generierten Bericht werden die Namen der Routinen ohne
Informationen über Offsets präsentiert. Offsets könnten für
eine detailliertere Analyse der Ausführung eines Programms
verwendet werden, werden hier aber nicht weiter behandelt.
Während der Timer-Interrupt-Verarbeitung oder bei der
Nachverarbeitung spiegelt die generierte auf Abtastung
basierende Profilinformation eine Abtastung von Aufrufstacks
wider, und nicht nur Blätter der möglichen Aufrufstacks wie in
manchen Programmzähler-Abtastverfahren. Ein Blatt ist ein
Knoten am Ende eines Zweiges, d. h. ein Knoten, der keine
weitere Abkömmlinge aufweist. Ein Abkömmling ist ein Kind
eines Elternknotens, und ein Blatt ist ein Knoten, der keine
Kinder hat.
In Fig. 8 ist der Aufrufstack mit den enthaltenen Stack
Frames in einem Diagramm dargestellt. Ein "Stack" ist ein
reservierter Speicherbereich, in dem ein Programm oder mehrere
Programme Statusdaten wie z. B. Prozedur- und
Funktionsaufrufadressen, übergebene Parameter und gelegentlich
auch lokale Variablen speichern. Ein "Stack Frame" ist ein
Teil des Stacks eines Threads, der einen lokalen Speicher
(Argumente, Rückkehradressen, Rückgabewerte und lokale
Variablen) für einen einzigen Funktionsaufruf darstellt. Jedem
aktiven Ausführungs-Thread ist ein Teil des Systemspeichers
als Stack-Bereich zugeteilt. Der Stack eines Threads besteht
aus Sequenzen von Stack Frames. Die Frames im Stack eines
Threads geben den Ausführungsstatus des Threads zu jedem
Zeitpunkt wieder. Das Stack Frames typischerweise miteinander
verknüpft sind (so verweist z. B. jeder Stack Frame auf den
vorhergehenden Stack Frame), ist es oft möglich, die Abfolge
der Stack Frames zurückzuverfolgen und den "Aufrufstack" zu
entwickeln. In einem Aufrufstack sind alle noch nicht
abgeschlossenen Funktionsaufrufe gespeichert, d. h. der
Aufrufstack spiegelt die Reihenfolge der Funktionsaufrufe zu
jedem Zeitpunkt wider.
Aufrufstack 800 enthält Informationen zur Identifikation der
gerade ablaufenden Routine, der Routine, von der sie
aufgerufen wurde usw., bis zurück zum Hauptprogramm.
Aufrufstack 800 enthält eine Anzahl von Stack Frames 802, 804,
806 und 808. In dem dargestellten Beispiel befindet sich Stack
Frame 802 oben auf dem Aufrufstack 800 und Stack Frame 808 an
der untersten Position von Aufrufstack 800. Der oberste Stack
Frame des Aufrufstacks wird auch als "Wurzel" bezeichnet. Der
Timer-Interrupt (den es in den meisten Betriebssystemen gibt)
wird so abgewandelt, dass der Programmzählerwert (pcv) des
unterbrochenen Thread zusammen mit dem Zeiger auf den gerade
aktiven Stack Frame für diesen Thread ermittelt wird. In der
Intel-Architektur wird dies typischerweise durch den Inhalt
folgender Register wiedergegeben: EIP (Programmzähler) und EBP
(Zeiger auf Stack Frame). Durch den Zugriff auf den gerade
aktiven Stack Frame kann die (typische) Stack Frame-
Verknüpfungskonvention genutzt werden, um alle Frames
miteinander zu verknüpfen. Ein Teil der
Standardverknüpfungskonvention schreibt auch vor, dass die
Funktionsrückkehradresse genau über dem Stack Frame der
aufgerufenen Funktion liegen muss; dies kann dazu verwendet
werden, die Adresse für die aufgerufene Funktion sicher zu
bestimmen. Die Verwendung einer Intel-basierten Architektur in
dieser Erläuterung ist nicht als Einschränkung zu betrachten.
In den meisten Architekturen werden Verknüpfungskonventionen
verwendet, nach denen ein modifizierter Profilierungs-
Interrupt-Handler auf ähnliche Weise navigieren kann.
Bei einem Timer Interrupt wird als erster Parameter der
Programmzählerwert ermittelt. Der nächste Wert ist der Zeiger
auf das oberste Element des aktuellen Stack Frame für den
unterbrochenen Thread. Im vorliegenden Beispiel würde dieser
Wert auf EBP 808a in Stack Frame 808 zeigen. EPB 808 verweist
wiederum auf EBP 806a in Stack Frame 806, und dieser auf EPB
804a in Stack Frame 804. Dieser EBP verweist auf EBP 802a in
Stack Frame 802. In den Stack Frames 802-808 befinden sich
die EIPs 802b-808b, die die Rückkehradresse der aufrufenden
Routine bezeichnen. Die Routinen können anhand dieser Adressen
identifiziert werden. Die Routinen werden also definiert,
indem alle Rückkehradressen vorwärts oder rückwärts durch den
Stack verfolgt werden.
In Fig. 9 ist ein Aufrufstack dargestellt. Ein Aufrufstack
wie Aufrufstack 900 wird gewonnen, indem der Aufrufstack
durchlaufen wird. Jedesmal, wenn ein periodisch
wiederkehrendes Ereignis, z. B. ein Timer Interrupt,
stattfindet, wird ein Aufrufstack gewonnen. Diese Aufrufstacks
können als Aufrufstack-Abrollprotokollsätze (oder einfach als
"Stack-Abrollung") zur Nachverarbeitung in der Protokolldatei
gespeichert oder auf der Stelle während der weiteren
Programmausführung verarbeitet werden.
In dem vorliegenden Beispiel enthält Aufrufstack 900 eine pid
(Prozesskennung) 902 und eine tid (Thread-Kennung) 904.
Aufrufstack 900 enthält außerdem die Adressen addr1 906, addr2
908 . . . addrN 910. In diesem Beispiel gibt addr1 906 den Wert
des Programmzählers zum Zeitpunkt des Interrupts an. Diese
Adresse liegt irgendwo im Bereich der unterbrochenen Funktion.
addr2 908 ist eine Adresse in dem Prozess, der die
unterbrochene Funktion aufgerufen hat. Bei
Datenverarbeitungssystemen, die auf einem Intel-Prozessor
basieren, ist dies die Rückkehradresse für diesen Aufruf; wenn
man von diesem Wert 4 subtrahiert, erhält man die Adresse des
eigentlichen Aufrufs, die Aufrufstelle. Diese entspricht EIP
808b in Fig. 8, addrN 910 ist die Spitze des Aufrufstack (EIP
802b). Der Aufrufstack, der zurückgegeben würde, wenn der
Timer Interrupt den Thread unterbrechen würde, dessen
Aufrufstack-Zustand in Fig. 8 dargestellt ist, würde aus
folgenden Elementen bestehen: einer pid (Prozesskennung des
unterbrochenen Thread), einer tid (Thread-Kennung des
unterbrochenen Thread), einer pcv (Programmzählerwert für den
unterbrochenen Thread, in Fig. 8 nicht dargestellt), EIP
808b, EIP 806b, EIP 804b und EIP 802b. In Fig. 9 ist pcv =
addr1, EIP 808b = addr2, EIP 806b = addr3, EIP 804b = addr4,
EIP 802b = addr5.
Fig. 10A zeigt eine Programmausführungssequenz zusammen mit
dem Zustand des Aufrufstack an jedem Funktionseinstiegs- und
Funktionsausstiegspunkt. In dieser Zeichnung sind Einstiege
und Ausstiege in regelmäßigen Abständen dargestellt; dies
dient aber nur der Vereinfachung der Darstellung. Wenn jede
Funktion (A, B, C und X in der Zeichnung) mit Ankern für
Einstiegs- und Ausstiegsereignisse instrumentiert wäre, wäre
es einfach festzustellen, wieviel Zeit in und unter jeder
Funktion aufgewendet wird. In Fig. 10A befindet sich zu
diesem Zeitpunkt 0 der ausgeführte Thread in Routine C. Der
Aufrufstack zum Zeitpunkt 0 lautet C. Zum Zeitpunkt 1 ruft
Routine C Routine A auf, und der Aufrufstack wird zu CA usw.
Es sei darauf hingewiesen, dass der Aufrufstack in Fig. 10A
ein rekonstruierter Aufrufstack ist, der generiert wird, indem
die ereignisbasierten Protokolldatensätze in einer
Protokolldatei so verarbeitet werden, dass die Ereignisse als
Einstiege in Methoden und Ausstiege aus Methoden verfolgt
werden. Das dazu verwendete Verfahren und die Datenstruktur
werden weiter unten ausführlicher beschrieben. Leider kann
diese Art der Instrumentierung aufwendig sein, zu
Beeinträchtigungen führen und manchmal schwierig anzuwenden
sein. Eine Profilierung auf Stichprobenbasis, bei der die
Abtastung auf den Aufrufstack des Programms beschränkt ist,
hilft, die Leistungseinbuße und andere Komplikationen, die
durch Ein-/Ausstiegsanker entstehen können, zu mindern.
In Fig. 10B wird das gleiche Programm ausgeführt, diesmal
aber in regelmäßigen Zeitabständen abgetastet. In diesem
Beispiel erfolgt die Unterbrechung mit einer Frequenz, die
zwei Zeitstempelwerten entspricht. Jede Abtastung enthält eine
Momentaufnahme des Aufrufstack des unterbrochenen Thread. Mit
diesem Verfahren sind nicht alle Aufrufstack-Kombinationen zu
erkennen - wie hier zu sehen ist, taucht Routine X in den
Aufrufstack-Abtastungen in Fig. 10B überhaupt nicht auf.
Diesen Nachteil der Abtastung kann man in Kauf nehmen. Die
zugrunde liegende Idee besteht darin, dass bei einer
geeigneten Abtastrate (z. B. 30-1000 mal pro Sekunde) die
Aufrufstacks identifiziert werden, in denen die meiste Zeit
aufgewendet wird. Dass einige Stacks fehlen ist kein großes
Problem, vorausgesetzt, es handelt sich dabei um
Kombinationen, für die wenig Zeit aufgewendet wird.
In den ereignisbasierten Protokollen liegt eine fundamentale
Annahme zugrunde, dass die Protokolle Informationen über
Einstiege in Routinen und die zugehörigen Ausstiege aus den
Routinen enthalten. Oft sind diese Ein-/Ausstiegspaare in den
Protokollen verschachtelt, da Routinen andere Routinen
aufrufen. Die zwischen dem Einstieg in eine Routine und dem
Ausstieg aus der Routine aufgewendete Zeit (oder der
verbrauchte Speicher) wird dieser Routine zugeschrieben; ein
Benutzer eines Profilierungs-Tools will aber möglicherweise
zwischen der direkt in einer Routine aufgewendeten Zeit und
der in anderen von ihr aufgerufenen Routinen aufgewendeten
Zeit unterscheiden.
In Fig. 10C ist an einem Beispiel dargestellt, wie Zeit von
zwei Routinen verbraucht werden kann: die "Hauptroutine" eines
Programms ruft Routine A zum Zeitpunkt t = 0 auf; Routine A
rechnet 1 ms lang und ruft dann Routine B auf; Routine B
rechnet 8 ms lang und kehrt dann zu Routine A zurück; Routine
A rechnet 1 ms lang und kehrt dann zur "Hauptroutine" zurück.
Aus der Sicht der "Hauptroutine" benötigte Routine A 10 ms für
die Ausführung, davon wurde aber der größte Teil der Zeit für
die Ausführung von Instruktionen in Routine B verwendet und
nicht für die Ausführung von Instruktionen in Routine A. Dies
ist eine nützliche Information für jemanden, der versucht, das
Beispielprogramm zu optimieren. Wenn Routine B von vielen
Stellen im Programm aus aufgerufen wird, könnte es auch
nützlich sein, zu wissen, wieviel Zeit der in Routine B
aufgewendeten Zeit auf das Konto von (oder den Aufruf durch)
Routine A zurückzuführen ist, und wieviel auf andere Routinen.
Ein wesentliches Konzept bei den Ergebnissen der hier
beschriebenen Methoden ist der Aufrufstack. Aufrufstack
besteht aus der gerade ablaufenden Routine, der Routine, von
der sie aufgerufen wurde usw., bis zurück zum Hauptprogramm.
Ein Profilierer kann eine höhere Thread-Ebene mit der pid/tid
(Prozess- und Thread-Kennung) hinzufügen. In jedem Fall wird
versucht, die protokollierten Ereignisse wie Einstiege in
Methoden und Ausstiege aus Methoden zu verfolgen wie in Fig.
10A, um die Struktur der Aufrufstack-Frames während der
Programmausführung zu verschiedenen Zeiten der Protokollierung
zu rekonstruieren.
Die Nachverarbeitung einer Protokolldatei kann einen Bericht
ergeben, in dem drei Arten der in einer Routine wie Routine A
aufgewendeten Zeit aufgeschlüsselt sind: (1) die Basiszeit -
d. h. die Zeit, die zur Ausführung von Code in Routine A selber
aufgewendet wird; (2) die kumulative Zeit (kurz "CUM-Zeit") -
d. h. die Zeit, die für die Ausführung in Routine A aufgewendet
wird plus die gesamte Zeit, die für die Ausführung aller von
Routine A aufgerufenen Routinen (und aller von diesen Routinen
aufgerufenen Routinen usw.) aufgewendet wird und (3) die nach
der Uhr verstrichene Zeit. Diese Art der Zeitinformation kann
aus den ereignisbasierten Protokolldatensätzen herausgelesen
werden, da jeder Datensatz mit einem Zeitstempel versehen ist.
Die kumulative Zeit einer Routine ist die Summe aller bei der
Ausführung der Routine aufgewendeten Zeiten plus der Zeit, die
für die Ausführung anderer Routinen aufgewendet wird, solange
diese Routine im Aufrufstack darunter liegt. In dem obigen
Beispiel in Fig. 10C beträgt die Basiszeit von Routine A 2 ms
und ihre kumulative Zeit 10 ms. Die Basiszeit von Routine B
beträgt 8 ms, und ihre kumulative Zeit beträgt ebenfalls 8 ms,
da sie keine anderen Routinen aufruft. Es sei darauf
hingewiesen, dass kumulative Zeit nicht generiert werden kann,
wenn ein Aufrufstack-Baum auf der Stelle generiert wird - die
kumulative Zeit kann nur nachträglich in der
Nachverarbeitungsphase eines Profilierungsdienstprogramms
berechnet werden.
Bei der verstrichenen Zeit verhält es sich so, dass wenn
während der Ausführung von Routine B das System einen
Interrupt erzeugte oder diesen Thread suspendierte, um einen
anderen Thread auszuführen, oder wenn Routine B durch das
Warten in einem Wartezustand oder bei einer Ein-/Ausgabe
blockiert war, Routine B und alle Einstiege im Aufrufstack
oberhalb von Routine B verstrichene Zeit ansammeln, aber keine
Basiszeit oder kumulative Zeit. Basiszeit und kumulative Zeit
werden nicht durch Interrupts, Zuteilung oder Blockierung
beeinflusst. Die Basiszeit nimmt nur zu, während eine Routine
ausgeführt wird, und die kumulative Zeit nimmt nur zu, während
die Routine oder eine im Aufrufstack unter ihr liegende
Routine ausgeführt wird.
In dem Beispiel in Fig. 10C ist die verstrichene Zeit von
Routine A mit ihrer kumulativen Zeit identisch - sie beträgt
10 ms. Wandeln wir nun das Beispiel etwas ab und nehmen wir
an, dass in der Mitte von B eine 1 ms dauernde Unterbrechung
stattgefunden hat wie in Fig. 10D. Die Basiszeit und die
kumulative Zeit von Routine A betragen unverändert 2 ms und 10
ms, die verstrichene Zeit beträgt aber jetzt 11 ms.
Auch wenn hier die Basiszeit, die kumulative Zeit und die
verstrichene Zeit als in Routinen aufgewendete Prozessorzeit
definiert wurde, ist die Profilierung für den Verbrauch fast
aller Systemressourcen für eine Gruppe von Routinen nützlich.
Darauf wird weiter unten im Zusammenhang mit Fig. 11B
ausführlicher eingegangen. Wenn in Fig. 100 Routine A zwei
Platten-E/A-Operationen initiiert hat und dann Routine B bei
ihrem Aufruf durch Routine A drei weitere E/A-Operationen
initiiert hat, hat Routine A zwei "Basis-E/As" und fünf
"kumulative E/As". "Verstrichene E/As" wären alle E/As
einschließlich derer von anderen Threads und Prozessen, die
zwischen dem Einstieg in Routine A und dem Ausstieg aus
Routine A erfolgt sind. Allgemeinere Definitionen der
Berechnungskonzepte bei der Profilierung: Basis - die Menge
der protokollierten Systemressourcen, die direkt von dieser
Routine verbraucht worden sind; kumulativ - die Menge der
protokollierten Systemressourcen, die von dieser Routine und
allen im Aufrufstack unter ihr liegenden Routinen verbraucht
worden sind; verstrichen - die gesamte Menge der (von allen
Routinen) verbrauchten protokollierten Systemressourcen
zwischen dem Einstieg in diese Routine und dem Ausstieg aus
dieser Routine.
Fig. 11A ist ein Diagramm, in dem eine aus Protokolldaten
generierte Baumstruktur dargestellt ist. Diese Figur zeigt
einen Aufrufstack-Baum 1100, in dem jeder Knoten in der
Baumstruktur 1100 einen Funktionseinstiegspunkt darstellt.
Außerdem sind in jedem Knoten in der Baumstruktur 1100 einige
statistische Angaben aufgezeichnet. In dem dargestellten
Beispiel enthält jeder Knoten 1102-1108 eine Adresse (addr),
eine Basiszeit (BASE), eine kumulative Zeit (CUM) und Zeiger
auf Eltern und Kinder. Wie erwähnt kann diese Art der
Zeitinformation aus den ereignisbasierten Protokolldatensätzen
herausgelesen werden, da jeder Datensatz mit einem Zeitstempel
versehen ist. Die Adresse stellt einen Funktionseinstiegspunkt
dar. Die Basiszeit bezeichnet die Zeit, die von dem Thread
direkt für die Ausführung dieser Funktion aufgewendet wird.
Die kumulative Zeit ist die Zeit, die von dem Thread, der
diese Funktion ausführt, und allen im Aufrufstack darunter
liegenden Funktionen aufgewendet wird. In dem dargestellten
Beispiel sind für jeden Knoten Zeiger enthalten. Ein Zeiger
ist der Elternzeiger, d. h. ein Zeiger auf den Elternknoten.
Außerdem enthält jeder Knoten einen Zeicher auf jeden seiner
Kindknoten.
Dem durchschnittlichen Fachmann ist klar, dass die
Baumstruktur 1100 auf verschiedene Weise implementiert werden
kann, und dass viele verschiedene Arten von Statistiken an den
Knoten geführt werden können und nicht nur die im Beispiel
dargestellten.
Der Aufrufstack wird entwickelt, indem an allen
Rückkehradressen zurückgeschaut wird. Diese Rückkehradressen
lösen sich in den Hauptteilen der Funktionen auf. Anhand
dieser Informationen kann zwischen verschiedenen Aufrufen der
gleichen Funktion unterschieden werden. Anders ausgedrückt,
wenn Funktion X zwei verschiedene Aufrufe von Funktion A hat,
kann die Zeit für diese Aufrufe separat berechnet werden. In
den meisten Berichten wird allerdings keine solche
Unterscheidung vorgenommen.
In Fig. 11B wird nun ein Aufrufstack-Baum beschrieben, der
alle in einem bestimmten Beispiel der Systemausführung
beobachteten Aufrufstacks reflektiert. An jedem Knoten des
Baums werden verschiedene statistische Angaben aufgezeichnet.
In dem Beispiel in Fig. 11B handelt es sich dabei um
zeitbasierte Statistikdaten. Die dargestellten statistischen
Angaben bezeichnen, wie oft der Stack erzeugt wurde, wieviel
Zeit insgesamt in dem Aufrufstack aufgewendet wurde, wieviel
Zeit insgesamt im Aufrufstack plus den von ihm aufgerufenen
Aufrufstacks aufgewendet wurde (kumulative Zeit), und wieviele
Ausprägungen dieser Routine über dieser Ausprägung stehen
(Rekursionstiefe).
An Knoten 1152 in Fig. 11B beispielsweise lautet der
Aufrufstack CAB, und zu diesem Knoten sind folgende
statistische Angaben vorhanden: 2: 3: 4: 1. Aufrufstack CAB
wird zum Zeitpunkt 2 in Fig. 10A zum ersten Mal erzeugt und
wird zum Zeitpunkt 3 verlassen. Aufrufstack CAB wird zum
Zeitpunkt 4 erneut erzeugt und zum Zeitpunkt 7 wieder
verlassen. Die erste Statistik besagt also, dass dieser
spezielle Aufrufstack, CAB, während der Protokollierung zwei
Mal erzeugt worden ist. Die zweite Statistik besagt, dass
Aufrufstack CAB drei Zeiteinheiten lang existiert (zum
Zeitpunkt 2, zum Zeitpunkt 4 und zum Zeitpunkt 6). Die dritte
Statistik bezeichnet die kumulative Zeit in Aufrufstack CAB
und den von Aufrufstack CAB aufgerufenen Aufrufstacks (d. h.
die Aufrufstacks, die CAB als Präfix haben, z. B. CABB). Die
kumulative Zeit in dem Beispiel aus Fig. 11B beträgt vier
Zeiteinheiten. Schließlich hat Aufrufstack CAB die
Rekursionstiefe eins, da keine der im Aufrufstack enthaltenen
Routinen rekursiv aufgerufen wurde.
Dem Fachmann ist klar, dass die in Fig. 11B dargestellte
Baumstruktur auf verschiedene Weise implementiert werden kann,
und dass an jedem Knoten verschiedene Arten von Statistiken
geführt werden können. In der hier beschriebenen
Ausführungsform enthält jeder Knoten im Baum Daten und Zeiger.
Die Datenelemente enthalten den Namen der Routine an diesem
Knoten und die vier erwähnten statistischen Angaben.
Selbstverständlich können an jedem Knoten noch viele andere
Arten statistischer Informationen gespeichert werden. In der
hier beschriebenen Ausführungsform enthalten die Zeiger für
jeden Knoten einen Zeiger auf den Elternknoten, einen Zeiger
auf den ersten Kindknoten (d. h. den am weitesten links
stehenden Kindknoten), einen Zeiger auf den nächsten
Geschwisterknoten und einen Zeiger auf die nächste Ausprägung
einer bestimmten Routine im Baum. In Fig. 11B enthält
beispielsweise Knoten 1154 einen Elternzeiger auf Knoten 1156,
einen Kindzeiger auf Knoten 1158, einen Geschwisterzeiger
gleich NULL (da Knoten 1154 keinen nächsten Geschwisterknoten
besitzt) und einen Ausprägungszeiger auf Knoten 1162. Dem
Fachmann ist klar, dass weitere Zeiger gespeichert werden
können, um die nachfolgende Analyse effizienter zu gestalten.
Außerdem können andere Strukturelemente wie Tabellen für die
Eigenschaften einer Routine, die über alle Ausprägungen
konstant sind, gespeichert werden, z. B. der Name der Routine.
Die Art der Leistungsdaten und Statistiken, die an jedem
Knoten verwaltet werden, ist nicht auf zeitbasierte
Leistungsstatistiken beschränkt. Die vorliegenden
Informationen können zu einer kompakten Darstellung vieler
Arten von Protokollinformationen, die viele Leistungsabfragen
unterstützt, verwendet werden. So können beispielsweise
anstelle von Zeitstatistiken die Anzahl der in jeder
aufgerufenen Methode (d. h. Routine) ausgeführten Java-
Bytecodes protokolliert werden. Die Baumstruktur in der
vorliegenden Erfindung würde dann keine zeitbasierten
Statistiken, sondern Statistiken über die ausgeführten
Bytecodes enthalten. Insbesondere die Angaben in der zweiten
und dritten Kategorie würden nicht die in jeder Methode
aufgewendete Zeit, sondern die Anzahl der ausgeführten
Bytecodes widerspiegeln.
Die Protokollierung kann auch zur Verfolgung der
Speicherzuteilung und -freigabe verwendet werden. Jedesmal,
wenn eine Routine ein Objekt erstellt, könnte ein
Protokolldatensatz generiert werden. Die erfindungsgemäße
Baumstruktur würde dann zur effizienten Speicherung und
Abfrage von Informationen über die Speicherzuteilung verwendet
werden. Jeder Knoten würde die Anzahl der Methodenaufrufe, den
in einer Methode zugeteilten Speicherplatz, den Speicherplatz,
der von den von dieser Methode aufgerufenen Methoden zugeteilt
wird, und die Anzahl der Methoden über dieser Ausprägung (d. h.
die Rekursionstiefe) wiedergeben. Dem Fachmann ist klar, dass
die erfindungsgemäße Baumstruktur zu einer sehr kompakten
Darstellung verschiedener Leistungsdaten verwendet werden kann
und eine große Vielfalt von Leistungsabfragen ermöglicht.
Die in Fig. 11B dargestellte Baumstruktur zeigt eine
Möglichkeit der bildlichen Darstellung der Daten. Die gleichen
Daten können einem Benutzer auch in Tabellenform präsentiert
werden wie in Fig. 12.
In Fig. 12 wird nun ein Aufrufstack-Baum in Tabellenform
beschrieben. Fig. 12 enthält eine Routine, pt_pidtid, die der
Hauptprozess bzw. Thread ist, der Routine C aufruft. Tabelle
12 enthält Datenspalten für die Ebene 1230, RL 1232, Aufrufe
1234, Basis 1236, CUM 1238 und Einrückung 1240. Ebene 1230 ist
die Baumebene (ausgehend von der Wurzel als Ebene 0) des
Knotens. RL 1232 ist die Rekursionsebene. Aufrufe 1234 gibt
an, wie oft dieser Aufrufstack vorkommt, d. h. wie oft genau
diese Aufrufstack-Konfiguration auftritt. Basis 1236
bezeichnet die Gesamtzeit, die in dem betreffenden Aufrufstack
beobachtet wurde, d. h. die Gesamtzeit, während der der Stack
genau diese Routinen enthalten hat. CUM 1238 ist die
Gesamtzeit in dem betreffenden Aufrufstack plus den darunter
liegenden tieferen Ebenen. Einrückung 1240 gibt die Ebene im
Baum in Form einer Einrückung an. Aus dieser Art von
Aufrufstack-Konfigurationsdaten ist jede Aufrufstack-
Konfiguration ersichtlich, mit der Information, wie oft sie
vorgekommen ist und wie lange sie sich im Stack befunden hat.
Diese Art von Information zeigt auch die dynamische Struktur
eines Programms, da zu erkennen ist, welche Routine welche
andere Routine aufgerufen hat. Sie vermittelt aber keine
Vorstellung über die zeitliche Abfolge im Aufrufstack-Baum. Es
kann nicht herausgelesen werden, ob Routinen auf einer
bestimmten Ebene vor oder nach anderen Routinen auf der
gleichen Ebene aufgerufen wurden.
Die bildliche Darstellung des Aufrufstack-Baums wie in Fig.
11B kann dynamisch an Ort und Stelle oder statisch mit einer
Protokolldatei als Eingabe erstellt werden. Fig. 13 ist ein
Flussdiagramm, in dem ein Verfahren zur Erstellung eines
Aufrufstack-Baums mit Hilfe einer Protokolltextdatei als
Eingabedatei dargestellt ist. In Fig. 13 wird der
Aufrufstack-Baum aufgebaut, um Moduleinstiegs- und
Modulausstiegspunkte aufzuzeigen.
In Fig. 13 wird zuerst festgestellt, ob weitere
Protokollsätze in der Protokolldatei vorhanden sind (Schritt
1350). Ist dies der Fall, so werden mehrere Daten aus dem
Protokollsatz abgerufen, u. a. die Zeit, ob es sich um ein
Einstiegs- oder um ein Ausstiegsereignis handelt, und der
Modulname (Schritt 1352). Dann wird das letzte Zeitinkrement
dem aktuellen Knoten im Baum zugeschrieben (Schritt 1354). Nun
wird festgestellt, ob es sich um einen Einstiegs- oder einen
Ausstiegsdatensatz handelt (Schritt 1356). Wenn es sich um
einen Ausstiegsdatensatz handelt, wird der Baum bis zum
Elternknoten durchlaufen (mit Hilfe des Elternzeigers), und
der aktuelle Baumknoten wird mit dem Elternknoten
gleichgesetzt (Schritt 1358). Handelt es sich um einen
Einstiegsdatensatz, so wird festgestellt, ob das Modul bereits
ein Kindknoten des aktuellen Baumknotens ist (Schritt 1360).
Ist dies nicht der Fall, wird ein neuer Knoten für das Modul
erstellt und unterhalb des aktuellen Baumknotens an den Baum
angehängt (Schritt 1362). Dann wird der Baum bis zum Knoten
des Moduls durchlaufen, und der aktuelle Baumknoten wird mit
dem Modulknoten gleichgesetzt (Schritt 1364). Die Anzahl der
Aufrufe bis zu aktuellen Baumknoten wird dann inkrementell
erhöht (Schritt 1366). Dieser Prozess wird für jeden
Protokolldatensatz in der Protokollausgabedatei wiederholt,
bis kein weiterer Protokolldatensatz mehr zu analysieren ist
(Schritt 1368).
Fig. 14 ist ein Flussdiagramm, in dem ein Verfahren zur
dynamischen Erstellung eines Aufrufstack-Baums bei der
Protokollierung während der Systemausführung dargestellt ist.
In Fig. 14 wird ein Ereignis bei seiner Protokollierung in
Echtzeit dem Baum hinzugefügt. Vorzugsweise wird für jeden
Thread ein separater Aufrufstack-Baum verwaltet. Der
Aufrufstack-Baum zeigt die bis zu diesem Zeitpunkt
aufgezeichneten Aufrufstacks, und ein Feld für den aktuellen
Baumknoten enthält die Angabe der aktuellen Position in einem
bestimmten Baum. Wenn ein Ereignis eintritt (Schritt 1470),
wird die Thread-Kennung ermittelt (Schritt 1471). Dann werden
die Zeit, die Art des Ereignisses (d. h. in diesem Fall, ob es
sich um einen Methodeneinstieg oder einen Methodenausstieg
handelt), der Name des Moduls (d. h. der Methode), die Position
des Aufrufstack des Threads und die Position des "aktuellen
Baumknotens" des Threads ermittelt (Schritt 1472). Das letzte
Zeitinkrement wird dem aktuellen Knoten im Baum zugeschrieben
(Schritt 1474). Nun wird festgestellt, ob es sich um ein
Einstiegs- oder ein Ausstiegsereignis handelt (Schritt 1476).
Wenn es sich um ein Ausstiegsereignis handelt, wird der Baum
bis zum Elternknoten durchlaufen (mit Hilfe des
Elternzeigers), und der aktuelle Baumknoten wird mit dem
Elternknoten gleichgesetzt (Schritt 1478). An dieser Stelle
kann der Baum dynamisch beschnitten werden, um den für seine
Verwaltung erforderlichen Speicherplatz zu reduzieren (Schritt
1479). Auf das Beschneiden wird weiter unten ausführlicher
eingegangen. Handelt es sich um ein Einstiegsereignis, so wird
festgestellt, ob das Modul bereits ein Kindknoten des
aktuellen Baumknotens ist (Schritt 1480). Ist dies nicht der
Fall, wird ein neuer Knoten für das Modul erstellt und
unterhalb des aktuellen Baumknotens an den Baum angehängt
(Schritt 1482). Dann wird der Baum bis zum Knoten des Moduls
durchlaufen, und der aktuelle Baumknoten wird mit dem
Modulknoten gleichgesetzt (Schritt 1484). Die Anzahl der
Aufrufe bis zu aktuellen Baumknoten wird dann inkrementell
erhöht (Schritt 1486). Nun geht die Steuerung an das
ausführende Modul zurück, und das dynamische Protokollierungs-
und Reduktionsprogramm wartet auf das nächste Ereignis
(Schritt 1488).
Ein Vorteil des in Fig. 14 beschriebenen dynamischen
Protokollierungs- und Reduktionsverfahrens ist die
Möglichkeit, das System mit einem endlichen Speicherpuffer
über lange Zeit zu protokollieren. Es können sehr detaillierte
Leistungsprofile ermittelt werden, ohne dass der
Protokollpuffer "unendlich groß" sein muss. In Verbindung mit
der dynamischen Beschneidung kann das in Fig. 14 dargestellte
Verfahren einen Protokollierungsmechanismus mit fester
Puffergröße unterstützen.
Die dynamische Protokollierung und Reduktion (und in manchen
Fällen auch die dynamische Beschneidung) ist besonders
vorteilhaft bei der Profilierung der Leistungsmerkmale von
Programmen mit langer Ausführungsdauer. Bei diesen lang
laufenden Programmen kann ein endlicher Protokollpuffer
erhebliche Auswirkungen auf die Menge nützlicher
Protokollinformationen, die gesammelt und analysiert werden
können, haben. Durch die dynamische Protokollierung und
Reduktion (und vielleicht die dynamische Beschneidung) kann
auch für ein lang laufendes Programm eine genaues und
informatives Leistungsprofil erstellt werden.
Viele lang laufende Anwendungen erreichen einen stetigen
Zustand, in dem jede mögliche Routine und jeder mögliche
Aufrufstack im Baum und in den Aktualisierungsstatistiken
vorhanden ist. Für solche Anwendungen können somit
Protokolldaten mit Hilfe der dynamischen Beschneidung auch
innerhalb der Zwänge beschränkter Speicheranforderungen ewig
aufgezeichnet und gespeichert werden. Der Wert der
Beschneidung liegt in der Reduzierung des Speicherbedarfs in
Situationen, in denen die Aufrufstacks praktisch unbegrenzt
sind. Unbegrenzte Aufrufstacks werden zum Beispiel von
Anwendungen erzeugt, die andere Anwendungen laden und
ausführen.
Die Beschneidung kann auf verschiedene Weise erfolgen, und es
ist eine Vielzahl von Beschneidungskriterien denkbar.
Beschneidungsentscheidungen können beispielsweise auf der
kumulativen Zeit, die einem Teilbaum zugeschrieben wird,
basieren. Die Beschneidung kann deaktiviert werden, solange
der für die Verwaltung des Aufrufstacks dedizierte
Speicherplatz einen Grenzwert nicht überschreitet. Wenn ein
Ausstiegsereignis festgestellt wird (wie Schritt 1478 in Fig.
14), wird die kumulative Zeit des aktuellen Knotens mit der
kumulativen Zeit des Elternknotens verglichen. Wenn das
Verhältnis zwischen diesen beiden kumulativen Zeiten einen
Schwellenwert für die Beschneidung (z. B. 0,1) nicht
überschreitet, werden der aktuelle Knoten und alle seine
Abkömmlinge von dem Baum entfernt. Der Algorithmus zur
Erstellung des Baums fährt wie bisher fort, indem er zum
Elternknoten zurückgeht und den aktuellen Knoten mit dem
Elternknoten gleichsetzt.
Zu dem beschriebenen Beschneidungsmechanismus sind zahlreiche
Abwandlungen denkbar. So kann beispielsweise der Grenzwert für
die Beschneidung erhöht oder verringert werden, um den
Beschneidungsgrad von einer sehr aggressiven Beschneidung bis
zu keiner Beschneidung zu regulieren. Auch globalere Verfahren
sind möglich, u. a. ein periodisches Überarbeiten des gesamten
Aufrufstack-Baums, bei dem alle Teilbäume entfernt werden,
deren individuelle kumulativen Zeiten keinen wesentlichen Teil
der kumulativen Zeiten des Elternknotens ausmachen.
Die Datenreduktion ermöglicht es Analyseprogrammen, viele
Fragen bezüglich der Aufwendung von Rechenzeit in dem
protokollierten Programm einfach und schnell zu beantworten.
Diese Informationen können gesammelt werden, indem der Baum
durchlaufen wird und die an verschiedenen Knoten im
Aufrufstack-Baum gespeicherten Daten zusammengeführt werden.
Daraus kann festgestellt werden, wieviel Zeit strikt in
Routine A aufgewendet wurde, wieviel Zeit insgesamt in Routine
A und den von Routine A direkt oder indirekt aufgerufenen
Routinen aufgewendet wurde, usw.
Fig. 15 ist ein Diagramm eines mit dem erfindungsgemäßen
Verfahren erzeugten Datensatzes. In Fig. 15 ist jede Routine
in Datensatz 1500 separat aufgeführt, zusammen mit
Informationen über die Routine. In der Aufrufspalte 1504
beispielsweise ist angegeben, wie oft die Routine aufgerufen
wurde. In der BASIS-Spalte 1506 ist die insgesamt in der
Routine aufgewendete Zeit angegeben, und in der CUM-Spalte
1508 die kumulative Zeit, die in der Routine und allen von ihr
aufgerufenen Routinen aufgewendet wurde. Die Namensspalte 1512
enthält den Namen der Routine.
In Fig. 16 ist ein Diagramm einer anderen Berichtsart, die
erstellt werden kann, dargestellt. Der in Fig. 16
dargestellte Bericht zeigt im wesentlichen die gleichen
Informationen wie Fig. 15, aber in einem etwas anderen
Format. Wie bei Fig. 15 enthält ein Diagramm 1600
Informationen über Aufrufe, Basiszeit und kumulative Zeit. In
Fig. 16 ist eine Protokollausgabe zu sehen, in der die in
verschiedenen Routinen aufgewendeten Zeiten in Millisekunden
angegeben sind. Fig. 16 enthält einen Abschnitt (begrenzt
durch horizontale Linien) für jede Routine, die in der
Protokollausgabe erscheint. Der Abschnitt enthält in der Zeile
"Selbst" Informationen über die Routine selber, in den Zeilen
"Eltern" Informationen darüber, von wem sie aufgerufen worden
ist, und in den Zeilen "Kind" Informationen darüber, welche
Routinen sie ihrerseits aufgerufen hat. Die Abschnitte sind
nach der kumulativen Zeit geordnet. Der dritte Abschnitt
betrifft Routine A, wie in der mit "Selbst" beginnenden Zeile
zu sehen ist. Den Zahlen in der Zeile "Selbst" dieses
Abschnitts ist zu entnehmen, dass Routine A in diesem
Protokoll dreimal aufgerufen wurde, und zwar einmal von
Routine C und zweimal von Routine B. In der Profilterminologie
sind Routine C und Routine B (unmittelbare) Eltern von Routine
A. Routine A ist ein Kind von Routine C und Routine B. Alle
Zahlen in der Zeile "Eltern" im zweiten Abschnitt sind
Aufschlüsselungen der entsprechenden Zahlen von Routine A.
Drei Mikrosekunden der sieben Mikrosekunden langen
Gesamtbasiszeit, die in A aufgewendet wurde, fallen auf den
Aufruf durch Routine C, drei weitere Mikrosekunden auf dem
ersten Aufruf durch Routine B und eine weitere Mikrosekunde
auf den zweiten Aufruf durch Routine B. Entsprechend wurde in
diesem Beispiel für jede Elternroutine die Hälfte der
kumulativen Zeit von 14 Mikrosekunden der Routine A
aufgewendet.
Im zweiten Abschnitt ist zu sehen, dass Routine C einmal
Routine B und einmal Routine A aufgerufen hat. Alle Zahlen in
den "Kind"-Zeilen sind Teilmengen der Zahlen aus dem Profil
des Kindes. So erfolgte beispielsweise von den drei Aufrufen
der Routine A in diesem Protokoll einer durch Routine C; von
der 7 Mikrosekunden umfassenden Gesamtbasiszeit der Routine A
entfielen drei Mikrosekunden auf den direkten Aufruf durch
Routine C; von der 14 Sekunden umfassenden kumulativen Zeit
der Routine A gehen sieben Mikrosekunden auf Routine C zurück.
Die gleichen Zahlen stehen in der ersten Zeile des dritten
Abschnitts, wo Routine C als eine der Elternroutinen von
Routine A aufgelistet ist. Die vier Beziehungen, die für alle
Abschnitte gelten, sind im oberen Teil von Fig. 16
zusammengefasst. Erstens ist die Summe der Zahlen in der
Spalte "Aufrufe" bei "Eltern" gleich der Anzahl der Aufrufe in
der Zeile "Selbst". Zweitens ist die Summe der Zahlen in der
Spalte "Basis" bei "Eltern" gleich der Basiszeit bei "Selbst".
Drittens ist die Summe der Zahlen in der Spalte "CUM" bei
"Eltern" gleich der kumulativen Zeit bei "Selbst". Diese
ersten drei Invarianten gelten, weil diese Eigenschaften die
Definition von Eltern sind; kollektiv sollen sie alle
Aktivitäten von "Selbst" ausmachen. Viertens entspricht "CUM"
in den "Kind"-Zeilen der Gesamtsumme der kumulativen Zeit von
"Selbst", mit Ausnahme der eigenen Basiszeit.
Die Programmabtastung kann Informationen aus dem Aufrufstack
enthalten und ein Profil liefern, das nicht nur die Abtastung
der Blätter, sondern des gesamten Aufrufstack widerspiegelt.
Darüber hinaus kann das auf Abtastung basierende
Profilierungsverfahren auch auf andere Arten von Stacks
angewendet werden. In Java-Programmen wird zum Beispiel viel
Zeit in einer als "Interpreter" bezeichneten Routine
aufgewendet. Würde nur der der Aufrufstack geprüft, so würde
das Profil in diesem Fall nicht viel nützliche Information
liefern. Da der Interpreter auch Informationen im eigenen
Stack, z. B. einem Java-Stack (mit eigenen
Verknüpfungskonventionen) protokolliert, kann der Prozess zum
Durchlaufen des Java-Stacks benutzt werden, um die
Aufrufsequenz aus der Perspektive des interpretierten Java-
Programms zu erhalten.
In Fig. 17 ist ein Bericht dargestellt, der aus einer
Protokolldatei generiert wurde, die sowohl ereignisbasierte
Profilierungsdaten wie Methodene 29223 00070 552 001000280000000200012000285912911200040 0002010050684 00004 29104instiege und Methodenausstiege
als auch Stack-Aufrollinformationen aus der auf Abtastung
basierenden Profilierung enthält. Fig. 17 entspricht im
wesentlichen Fig. 12, wo ein Aufrufstack-Baum als Bericht
dargestellt ist, wobei Fig. 17 aber eingebettete
Stackdurchlaufinformationen enthält. Der Aufrufstack-Baum 1700
enthält zwei Stack-Aufrollungen, die in der durch insgesamt
342 Ticks dargestellten Zeitperiode generiert wurden. Die
Stackaufrollkennung 1702 kennzeichnet den Anfang der
Stackaufrolldaten 1706 wobei die nach rechts eingerückten
Routinennamen die Stack-Informationen enthalten, die beim
Durchlaufen des Stacks erkannt werden konnten. Die
Stackaufrollkennung 1704 kennzeichnet den Anfang der
Stackaufrolldaten 1708. In diesem Beispiel bezeichnet "J:"
eine interpretierte Java-Methode und "F:" eine native
Funktion, z. B. eine native Funktion in JavaOS. Ein Aufruf
einer nativen Methode durch eine Java-Methode erfolgt mittels
"ExecuteJava". Daher kann an der Stelle, wo der Stackdurchlauf
einen Stack Frame für ein "ExecuteJava" erreicht, kein
weiterer Schritt durch den Stack folgen, da die Stack Frames
aufhören. Der Prozess zum Erstellen eines Baums, der sowohl
ereignisbasierte Knoten als auch auf Abtastung basierende
Knoten enthält, wird weiter unten ausführlicher beschrieben.
In diesem Fall bezeichnen die Kennungen 1702 und 1704 auch den
Hauptcode für diese Stack-Aufrollung.
Fig. 18 ist eine Tabelle, in der Haupt- und Untercodes
aufgeführt sind, die dazu benutzt werden können, Module für
die Profilierung zu instrumentieren. Ein Codesatz kann dazu
verwendet werden, verschiedene Arten von
Profilierungsfunktionen in einer bestimmten
Profilierungssitzung zu aktivieren und zu deaktivieren.
Wie in Fig. 18 zu sehen ist, wird beispielsweise der
Untercode für eine Stackaufrollung mit 0x7fffffff bezeichnet
und kann für zwei verschiedene Zwecke eingesetzt werden. Der
erste Zweck, hier mit dem Hauptcode 0x40 bezeichnet, ist die
Stackaufrollung bei einem Timer-Interrupt. Der zweite Zweck,
hier mit dem Hauptcode 0x41 bezeichnet, ist die
Stackaufrollung in einer instrumentierten Routine. Wenn die
Stackdaten mit Haupt- und Untercodes in eine Protokolldatei
ausgegeben werden, können die in der Datei erscheinende
Protokolldaten auf die durch Haupt- und Untercodes
signalisierte Weise angemessen analysiert werden.
Andere Beispiele in der Tabelle zeigen einen Profil- oder
Hauptcodezweck der Ablaufverfolgung von JIT-Methoden mit einem
Hauptcodewert von 0x50. Die Protokollierung gejitteter
Methoden kann anhand des Untercodes unterschieden werden, der
einen Methodenaufruf oder das Verlassen einer Methode
signalisiert. Im Gegensatz dazu bezeichnet ein Hauptcode von
0x30 einen Profilierungszweck der Instrumentierung von
interpretierten Methoden, während ein Untercode mit den
gleichen Werten einen Methodenaufruf oder das Verlassen einer
Methode signalisiert.
In Fig. 17 kann eine Verbindung zwischen der Verwendung von
Haupt- und Untercodes, der Instrumentierung von Code und der
Nachverarbeitung von Profildaten hergestellt werden. In dem in
Fig. 17 dargestellten generierten Bericht ist zu sehen, dass
die Stackaufrollkennungen den Wert 0x40 haben, was nach der
Tabelle in Fig. 18 eine als Reaktion auf einen Timer-
Interrupt generierte Stackabrollung ist. Diese Art der
Stackaufrollung kann als Reaktion auf einen Interrupt erfolgt
sein, der erzeugt wurde, um ein auf Abtastung basierendes
Profil der ausgeführten Software zu generieren.
Wie in der letzten Spalte der Tabelle in Fig. 18 zu sehen
ist, kann durch Verwendung eines Dienstprogramms, das einen
Anker in ein zu profilierendes Softwaremodul setzt, eine
Stackaufrollung in eine Routine instrumentiert werden. In
diesem Fall wird die Ausgabe für diese Art der Stackaufrollung
mit einem Hauptcode von 0x41 gekennzeichnet.
Bei der Profilierung eines ausführbaren Programms würde der
Profilierer im Idealfall Paare zusammengehöriger Einstiegs-
und Ausstiegsereignisse empfangen. Dies ist aber nicht oft der
Fall. In einem typischen Beispiel kann die Protokollierung
beginnen, nachdem ein Teil des ausführbaren Programms bereits
ausgeführt worden ist. Dies kann geschehen, wenn der
Mechanismus zum Starten des Profilierers dynamisch aktiviert
wird. In diesem Fall empfängt der Profilierer möglicherweise
Ausstiegsereignisse, ohne dass zuvor die zugehörigen
Einstiegsprotokolldatensätze empfangen wurden, d. h. ohne ein
zugehöriges Einstiegsereignis. In diesem Fall hat das
Ausstiegsereignis keine Entsprechung.
Ein weiteres Beispiel wäre, dass es in einer
Profilierungssitzung mehrere Ausführungspfade gibt, die nicht
korrekt als praktische Angelegenheit instrumentiert sind. Dies
kommt bei Ausnahmepfaden häufig vor. Im Fall von
Ausführungspfaden empfängt der Profilierer Einstiegsereignisse
ohne die zugehörigen Ausstiegsereignisse, da ein Ausnahmepfad
inhärent ein abruptes Verlassen einer Routine oder einer
Methode bewirkt.
In einem weiteren Beispiel von Ereignissen ohne entsprechendes
Gegenstück kann die Instrumentierung des ausführbaren Codes
möglicherweise nicht automatisch durchgeführt werden. Um eine
ereignisbasierte Profilierung zu verwenden, muss ein
ausführbares Programm mit Ankern für die Protokollierung von
Ein- und Ausstiegen instrumentiert werden. Bei einem manuell
instrumentierten Code kann es vorkommen, dass einem
Programmierer ein Fehler unterläuft und er keine
zusammengehörigen Ein- und Ausstiegsprotokollanker in eine
Routine einfügt. In diesem Fall kann es dazu kommen, dass der
Profilierer ein Ausstiegsereignis für eine Routine ohne
entsprechenden Einstiegsprotokollsatz empfängt.
In jedem dieser Beispiele ist es wichtig, den
Ausführungspfadfluss zu ermitteln und eine sinnvolle
Darstellung der Ausführungspfade zu erstellen. Man kann
versuchen, diese Fehlertypen im Profilierer zu erkennen und zu
beheben. Die Protokollverarbeitung kann in allen Fehlerfällen
fortgesetzt werden, und in der Regel werden sowohl für häufige
als auch für ungewöhnliche Probleme vernünftige Ausnahmepfade
festgelegt.
Die Fehlerbehebungsverarbeitung kann sowohl in Form einer
Echtzeitverarbeitung des Protokolls als auch in einer
Nachverarbeitungsphase der ausgegebenen Protokolldaten
erfolgen. Bei der Protokollverarbeitung in Echtzeit kann ein
Aufrufstack-Baum erstellt werden wie weiter oben im
Zusammenhang mit Fig. 11A und Fig. 11B beschrieben. Zu jedem
Zeitpunkt während der Erstellung des Aufrufstack-Baums wird
ein Zeiger auf einen aktuellen Knoten verwaltet, der die
Routine, die zuletzt als gerade ausgeführt identifiziert
wurde, darstellt.
Wenn das gerade verarbeitete Ereignis ein Einstiegsereignis
ist, kann davon ausgegangen werden, dass das Einstiegsereignis
einen Aufruf durch die vom aktuellen Knoten repräsentierte
Routine darstellt. Da noch nicht festgestellt werden kann, ob
ein Fehler aufgetreten ist, bei dem ein Ausstiegsereignis im
Ausführungsfluss vor dem gerade verarbeiteten Ereignis fehlt,
wird davon ausgegangen, dass Einstiegsereignisse keine
Fehlerbedingung enthalten. Selbst wenn nachträglich eine
Fehlerbedingung erkannt wird, wird die Verarbeitung von
Einstiegsereignissen auf die gleiche Weise fortgesetzt, ob nun
in dem durch die generierten Ereignisse dargestellten
Ausführungsfluss eine Fehlerbedingung aufgetreten ist oder
nicht.
Bei der Verarbeitung eines Ereignisses wird angenommen, dass
das Ausstiegsereignis einen Ausstieg aus der aktuellen Routine
gemäß der Darstellung in der Aufrufstack-Baumstrukur
darstellt. Das Ausstiegsereignis kann aber eine Routine
identifizieren, die nicht in den aktuellen Baumknoten passt,
d. h. ein Ausstiegsereignis und der aktuelle Knoten im
Aufrufstack-Baum passen nicht zusammen, so dass ein
Entsprechungsfehler vorliegt. In den Protokolldaten fehlt
deshalb mindestens ein Einstiegsereignis. Obwohl anhand der
Protokolldaten nicht festgestellt werden kann, wie viele
Ereignisse fehlen, kann man doch versuchen, einen Knoten im
Aufrufstack-Baum zu ermitteln, der das gerade verarbeitete
Ausstiegsereignis darstellt.
Ergänzend ist zu sagen, dass beim Empfang eines Einstiegs-
oder Ausstiegsereignisses ein aktueller Zeitstempel (oder ein
anderes ausführungsbezogenes Merkmal) erfasst werden kann, und
dass das Zeitinkrement (oder eine andere ausführungsbezogene
Metrik) zwischen dem gerade verarbeiteten Ereignis und dem
vorausgehenden Ereignis auf den aktuellen Knoten angewandt
wird. Diese Standardregel funktioniert selbst in Fällen, wo
ein Fehler mit nicht zusammenpassenden Ein- und
Ausstiegsereignissen erkannt wird, recht gut, da der aktuelle
Knoten die letzte als gerade ausgeführt erkannte Routine
darstellt und mindestens ein Teil der Zeit (oder einer anderen
ausführungsbezogenen Metrik) zwischen dem letzten Ereignis und
dem gerade verarbeiteten Ereignis im aktuellen Knoten
aufgewendet wurde.
Fig. 19 ist ein Flussdiagramm, in dem die Verarbeitung von
Beendigungsereignissen einschließlich der
Fehlerbehebungsverarbeitung in einem Ausführungsfluss, der
Fehler in Form nicht einander zuzuordnender Ereignisse
enthalten kann, dargestellt ist. Der im Flussdiagramm
dargestellte Prozess geht davon aus, dass ein gerade
verarbeitetes Ereignis als Ausstiegsereignis erkannt wurde.
Auf diese Weise kann der in Fig. 19 dargestellte Prozess
Schritt 1478 in Fig. 14 ersetzen.
In diesem Beispiel ist X der Modulname des Moduls, das durch
das Ausstiegsereignis verlassen wird, Y ist der Modulname des
aktuellen Knotens des Aufrufstack-Baums, und R ist der
Modulname des Wurzelknotens. Für die Baumknoten gelten
bestimmte Beziehungen, so z. B., dass der Elternknoten von NODE
als PAR(NODE) bezeichnet wird und der Kindknoten von NODE als
CHILD(NODE).
Der Prozess in Fig. 19 beginnt damit, dass festgestellt wird,
ob das verlassene Modul X das gleiche ist wie der aktuelle
Knoten Y, d. h. ob der Modulname des verlassenen Moduls X dem
Modulnamen des aktuellen Knotens Y entspricht (Schritt 1902).
Wenn dies der Fall ist, handelt es sich um einen normalen
Ausstieg ohne Fehler. Der Baum wird zurückverfolgt, d. h. zum
Elternknoten des aktuellen Knotens verfolgt (Schritt 1904),
und der Prozess ist in Bezug auf das gerade verarbeitete
Ausstiegsereignis abgeschlossen.
Wenn das verlassene Modul nicht mit dem aktuellen Knoten Y
identisch ist, wird festgestellt, ob der aktuelle Knoten Y mit
dem Wurzelknoten R identisch ist (Schritt 1906). Dies ist der
häufigste Fehlerfall, der eintritt, wenn das
Einstiegsereignis, das dem gerade verarbeiteten
Ausstiegsereignis entspricht, erfolgte, bevor die
Protokollierung aktiviert wurde. Wenn der aktuelle Knoten mit
dem Wurzelknoten identisch ist, wird der Baum "repariert",
indem der Wurzelknoten R in das verlassene Modul X umbenannt
wird und Modul X die Möglichkeit bekommt, alle Metriken, die
zu diesem Zeitpunkt im Wurzelknoten R vorhanden sind, zu
übernehmen (Schritt 1908). Dann wird für die Wurzel des Baumes
ein neuer Knoten erstellt und als Elternknoten des Knotens für
das verlassene Modul X angehängt, d. h. PAR(X) = R und CHILD(R)
= X (Schritt 1910). Die Baumstruktur sieht jetzt genauso aus,
als wenn die Protokollierung mit einem Einstieg in Modul X
begonnen hätte. Nun ist der Prozess in Bezug auf die
Verarbeitung des Ausstiegsereignisses, wenn der aktuelle
Knoten der Wurzelknoten ist, abgeschlossen.
Wenn der aktuelle Knoten nicht mit dem Wurzelknoten identisch
ist, wird der Baum zurückverfolgt, d. h. der Zeiger des
aktuellen Knotens verweist auf den Elternknoten des aktuellen
Knotens Y (Schritt 1912). Es wird festgestellt, ob das
verlassene Modul X das gleiche ist wie der aktuelle Knoten Y,
d. h. ob der Modulname des verlassenen Moduls X dem Modulnamen
des aktuellen Knotens Y entspricht (Schritt 1914). Ist dies
der Fall, fährt die Verarbeitung mit Schritt 1904 fort, um die
Verarbeitung des gerade verarbeiteten Ausstiegsereignissatzes
fortzusetzen. In diesem Fall muss der Baum über mehrere
Schritte zurückverfolgt werden, um einen passenden
Ausstiegsknoten zu finden. Dies kann folgende Gründe haben:
(1) ein langer "Sprung", der verwendet wird, um von einer
verschachtelten Fehlerbedingung zurückzukehren; (2) ein nicht
instrumentierter Ausnahmeverarbeitungspfad; oder (3) eine
fehlerhafte Instrumentierung, die dazu führt, dass ein oder
mehrere Ausstiegsanker fehlen.
Wenn das verlassene Modul nicht mit dem aktuellen Knoten Y
identisch ist, wird festgestellt, ob der aktuelle Knoten Y mit
dem Wurzelknoten R identisch ist (Schritt 1916). Ist dies
nicht der Fall, verzweigt der Prozess zurück zu Schritt 1912.
Ist der aktuelle Knoten Y mit dem Wurzelknoten R identisch,
wird der Baum "repariert", indem zu Schritt 1908 und Schritt
1910 verzweigt wird. Die Interpretation der zu behebenden
Situation ist aber anders als oben beschrieben. Die
Feststellung in Schritt 1916 erkennt einen schweren Fehler,
möglicherweise aufgrund von Instrumentierungsfehlern oder
Schwierigkeiten bei der Protokolldatenerfassung, und bei
Bedarf kann eine Meldung, dass es sich um einen schweren
Fehler handelt, ausgegeben werden.
Auf diese Weise kann mit dem in Fig. 19 beschriebenen Prozess
eine Aufrufstack-Baumdarstellung erzeugt werden, die nützliche
Informationen liefert, obwohl einige der Knoten keine exakte
Entsprechung zum Ausführungsfluss des ausgeführten Programms
darstellen.
Wie oben erwähnt kann es sein, dass die Protokollierung erst
beginnt, nachdem schon ein Teil des ausführbaren Programms
abgelaufen ist, wodurch es zu fehlenden Ein- und
Ausstiegsereignissen im Protokollablauf kommen kann, und wenn
der Profilierer ein Ereignis empfängt, entspricht dieses
keinem Knoten im Aufrufstack-Baum. Diese Art von
Entsprechungsfehler kann am Anfang einer Profilierungsphase
vorkommen, wenn die Protokollierung eines Programms beginnt,
sie kann aber auch bei der auf Abtastung basierenden
Profilierung gemäß einer bevorzugten Ausführungsform der
vorliegenden Erfindung vorkommen - falls die Generierung der
Protokolldaten unterbrochen und dann wiederaufgenommen wurde,
können entsprechungslose Ein- und Ausstiegsereignisse im
Ausführungsfluss vorkommen. Der Prozess der Unterbrechung und
Wiederaufnahme der ereignisbasierten Profilierung, d. h. die
auf Abtastung basierende Profilierung von Ereignissen, hat im
Vergleich mit anderen Arten der Profilierung gewisse Vorteile.
Die Erzeugung eines Aufrufstack-Baums während einer
kontinuierlichen ereignisbasierten Profilierung hat aufgrund
der Baumerstellung und Metrikerfassung im Profilierungsprozess
eine erhebliche Verminderung der Systemleistung zur Folge. Die
Aufrollung von Stacks bei der auf Abtastung basierenden
Profilierung ist nicht immer zuverlässig und kann inhärente
Implementierungsprobleme haben; so kann es beispielsweise
unmöglich sein, eine Zeigerkette im Aufrufstack zu verfolgen,
oder der profilierte Programmcode entspricht nicht den
Standardkonventionen. Selbst wenn die Stackaufrollungen
zuverlässig sind, liefern sie für die zu profilierenden
Routinen keine Informationen über die Länge der Ausführung.
Die periodische Abtastung von Einstiegs- und Ausstiegsankern
liefert daher ein gewisses strukturelles und quantitives Maß
der Ausführung eines Programms bei geringerer Beeinträchtigung
der Systemleistung als bei einer kontinuierlichen
ereignisbasierten Profilierung und ohne totale Abhängigkeit
von Stackaufrollungen.
Fig. 20 ist ein Flussdiagramm, in dem ein Prozess zur auf
Abtastung basierten Profilierung von Aufruf-
/Beendigungsereignissen unter Verwendung benutzerdefinierter
Metriken zur Erzeugung unabhängiger Aufrufstack-Baumsegmente
dargestellt ist. Der Prozess geht davon aus, dass die
beschriebenen Aktionen für jeden Thread separat ausgeführt
werden, d. h. der Profilierer würde die gleichen Aktionen oder
die gleiche Verarbeitung für jeden einzelnen pidtid-Wert
durchführen, d. h. Segmente eines Aufrufstack-Baums können
nicht nur anhand der Abtastperiode identifiziert werden,
sondern auch anhand des pidtid-Wertes. Außerdem kann der
Profilierer einen Sequenzwert für die Abtastperiode verwalten
und inkrementieren, der eine Ordnungsnummer für die
Abtastperioden liefert.
Der Prozess beginnt damit, dass der Profilierer vom Benutzer
angegebene Metrikwerte akzeptiert, die der Profilierer zur
Steuerung der auf Abtastung basierten Profilierung verwenden
soll (Schritt 2002). Diese Metrikwerte können z. B. in
Umgebungsvariablen gespeichert oder durch
Befehlszeilenparameter eingegeben werden. Alternativ enthält
der Profilierer Standardmetrikwerte, so dass der Benutzer
keine Metrikwerte eingeben muss. An einem Zeitpunkt wird die
Profilierungsphase eines Programms schließlich initiiert
(Schritt 2004).
Der Profilierer deaktiviert dann die Protokollierung für einen
vom Benutzer angegebenen Metrikwert (Schritt 2006) und führt
in dieser Zeit keine Protokollverarbeitung durch (Schritt
2008). Nach Ablauf dieser Zeit erwacht der Profilierer wieder
und aktiviert die Protokollverarbeitung in Echtzeit (Schritt
2010). Der Profilierer erstellt ein neues, unabhängiges
Aufrufstack-Baumsegment anhand der Einstiegs-
/Ausstiegsereignisse mit einer Fehlerverarbeitung während
einer Periode, die nach einem anderen vom Benutzer angegebenen
Metrikwert gemessen wird (Schritt 2012).
Nun wird festgestellt, ob die Programmausführung abgeschlossen
ist (Schritt 2014), und wenn dies nicht der Fall ist,
verzweigt der Prozess zu Schritt 2006 zurück, um die
Profilierung der Programmausführung fortzusetzen. Wenn die
Programmausführung abgeschlossen ist, gibt der Profilierer die
in der Profilierungsphase generierten Aufrufstack-Baumsegmente
aus (Schritt 2016). In der Nachverarbeitungsphase werden die
Aufrufstack-Baumsegmente zu einem einzigen Aufrufstack-Baum
verschmolzen (Schritt 2018), und der Prozess ist
abgeschlossen. Das "Verschmelzen" eines Baums ist definiert
als Durchlaufen eines ersten Baums, um einen zweiten Baum zu
erstellen, der die Vereinigung des ersten und des zweiten
Baums enthält. In diesem Fall werden alle Aufrufstack-
Baumsegmente zu einem einzigen Baum verschmolzen, d. h. es wird
durch Vereinigung aller Aufrufstack-Baumsegmente ein einziger
Baum generiert.
Jedes Aufrufstack-Baumsegment ist eine eindeutige Aufzeichnung
der Aufrufsequenz zwischen Routinen in dieser Abtastperiode.
Ein Aufrufstack-Baumsegment kann als Baumdatenstruktur
klassifiziert werden. Für jede Abtastperiode wird ein
unabhängiger Baum erstellt, so dass ein Wald von Bäumen
entsteht, der auf den pidtid-Werten im zeitlichen Verlauf
basiert. Obwohl jede Abtastperiode einen eigenen Aufrufstack-
Baum erzeugt, wird der Begriff "Aufrufstack-Baumsegment"
benutzt, um zu betonen, dass jeder dieser Aufrufstack-Bäume
aus diesen Periode relativ klein sein kann im Vergleich zu
einem kompletten Aufrufstack-Baum, der die Aufrufsequenzen
zwischen den Routinen für einen vollständige Profilierungslauf
eines ausführbaren Programms aufzeichnet. Der Begriff
"Aufrufstack-Baumsegment" wird auch benutzt, um zu betonen,
dass diese Aufrufstack-Bäume nur ein Mittel zu dem Zweck sind,
am Ende einen resultierenden Aufrufstack-Baum für alle
Abtastperioden zu erzeugen. Deshalb ist die Information in
einem Aufrufstack-Baumsegment im Vergleich zu der gesamten
Profilinformation, die bei der Profilierung des Programms
generiert wird, nur ein "Segment" der Profilinformation für
eine Abtastperiode.
Ein Aufrufstack-Baumsegment von einer Abtastperiode wird
insofern als "unabhängig" bezeichnet als jedes Aufrufstack-
Baumsegment in dieser Vorstellung eine eigene Wurzel und
eigene Knoten besitzt, die die Abfolge der Routinen- oder
Methodenaufrufe zwischen den Routinen entsprechend der
Baumstruktur wiedergeben. Der Profilierer kann aber eine
andere Datenstruktur verwalten, die diese Aufrufstack-
Baumsegmente assoziativ speichert - in diesem Kontext muss
"Unabhängigkeit" nicht bedeuten, dass die einzelnen
Datenstrukturen nicht mit anderen Datenstrukturen verknüpft
sind.
Da die Aufrufstack-Baumsegmente anhand der pidtid-Werte
identifizierbar sind, kann der Profilierer eine Art
Datenstrukur für jede pidtid verwalten. Er kann beispielsweise
eine verknüpfte Liste verwalten, in der jedes Element der
Wurzelknoten eines kompletten Aufrufstack-Baumsegments ist.
Anders ausgedrückt können miteinander in Verbindung stehende
Aufrufstack-Baumsegmente assoziativ verknüpft werden, so wie
der Profilierer dies für erforderlich hält, um die
Aufrufstack-Baumsegmente zu verwalten und zu protokollieren.
Der Benutzer kann eine Abtastzeit und eine Anzahl der
Ereignisse für jede Abtastung identifizieren. Bei jeder
Abtastung wird ein Aufrufstack-Baum generiert. Nach Abschluss
der Profilierungsphase kann der Profilierer Tausende dieser
Bäume, d. h. einen "Wald" von Bäumen, besitzen. Alternativ kann
der Profilierer in regelmäßigen Abständen die Aufrufstack-
Bäume zur Nachverarbeitung in eine Datei ausgeben. Dieser Wald
von Bäumen kann dann bei der Nachverarbeitung verschmolzen
werden.
Der Benutzer kann beispielsweise eine Wartezeit oder Pause von
zwei Sekunden und eine aus tausend Ereignissen bestehende
Protokollierungsperiode angeben. Der Profilierer erstellt dann
alle zwei Sekunden tausend Ereignis-Momentaufnahmen. Nach
tausend Ereignissen deaktiviert der Profilierer die
Verarbeitung von Einstiegs- und Ausstiegsereignissen und
wartet zwei Sekunden lang. Nachdem der Profilierer sich
entschließt, wieder mit der Protokollverarbeitung zu beginnen,
z. B. nach einem Timer-Interrupt, aktiviert er die Verarbeitung
von Ein-/Ausstiegsereignissen und ermöglicht die Fortsetzung
der Ereignisverarbeitung. Der Profilierer durchläuft auf diese
Weise eine Schleife, bis die Ausführung des Jobs abgeschlossen
ist.
Alternativ könnte die Abtastung nicht durch eine Anzahl von
Ereignissen, sondern durch eine Zeitangabe definiert werden.
In diesem Fall könnte der Benutzer zum Beispiel eine 10
Millisekunden lange Abtastdauer angeben, die einmal pro
Sekunde stattfindet. In einer bevorzugten Ausführungsform kann
der Benutzer verschiedene Arten von ausführungsbezogenen
Metriken für die Wartezeit und/oder die Abtastperiode wählen.
Zusätzlich kann der Profilierer in jeder Routine neben der
Ausführungszeit verschiedene ereignisbezogene Merkmale
überwachen.
Fig. 21 ist ein Flussdiagramm, in dem der Prozess dargestellt
ist, durch den ein Baum, der sogenannte Quellbaum, zu einem
zweiten Baum, dem sogenannten Zielbaum, hinzugefügt wird, um
eine Vereinigung zwischen den beiden Bäumen zu schaffen.
Dahinter steht die Absicht, den Quellbaum von der Wurzel des
Zielbaus ausgehend in den Zielbaum zu kopieren. Wenn im
Zielbaum bereits ein Teil des Quellbaums an der Wurzel
beginnend als Kind der Wurzel existiert, darf kein neuer,
doppelt vorhandener Knoten im Zielbaum erstellt werden,
sondern die vorhandenen Knoten im Zielbaum müssen
wiederbenutzt werden, wobei ihre Profilierungsmetriken addiert
werden.
Jeder Quellbaumknoten S durch die Definition von "Baum"
besitzt einen eindeutigen Elternknoten par(S) im Quellbaum;
davon ausgenommen ist nur der Wurzelknoten Sroot, der keinen
Elternknoten besitzt. Außerdem gibt es zu jedem S schließlich
einen eindeutigen entsprechenden Knoten T(S) im Zielbaum.
Jedes S wird als Kind seines eindeutigen entsprechenden
Elternknotens im Zielbaum kopiert. Anders ausgedrückt: Wenn S1
ein Kind von S2 ist, dann ist T(S1) ein Kind von T(S2). par(S)
muss also in den Zielbaum kopiert worden sein, bevor S kopiert
werden kann. Alle Profilmetriken für den Quellknoten werden
direkt zu den entsprechenden Feldern des Zielknotens addiert.
Zu diesen Daten zählen die Anzahl der Aufrufe, die kumulative
Zeit und die Basiszeit. Damit der Kopierprozess starten kann,
wird diese Anforderung für die Wurzel des Quellbaums
ausgesetzt; es wird angenommen, dass T(par(Sroot)) die Wurzel
des Zielbaums ist. Die Profilmetriken für den Wurzelknoten des
Quellbaums werden zu dem Wurzelknoten des Zielbaums addiert,
und der Zielknoten des Quellbaums wird als verarbeitet
markiert (Schritt 2102).
Jeder Knoten S des Quellbaums, dessen Elternknoten bereits in
den Zielbaum kopiert worden ist, kann als nächster zu
kopierender Knoten ausgewählt werden (Schritt 2104). Dann wird
entschieden, ob T(par(S)) bereits einen Kindknoten besitzt,
der die gleiche Routine darstellt wie S (Schritt 2106). Wenn
dies nicht der Fall ist, wird im Zielbaum ein neuer Kindknoten
erstellt (Schritt 2108), der Routinenname des neuen Knotens
wird auf den Routinennamen von S gesetzt (Schritt 2110), und
die Profilmetriken im Zielknoten wie z. B. die Anzahl der
Aufrufe des Zielknontens wird auf Null gesetzt (Schritt 2112).
Die Profilmetriken in S wie z. B. die Anzahl der Aufrufe von S
werden dann zu den Profilmetriken addiert, die im (neu
erstellten oder bereits vorher vorhandenen) entsprechenden
Knoten T(S) im Zielbaum gespeichert sind, und der Quellknoten
wird als verarbeitet markiert (Schritt 2114). Dann wird
festgestellt, ob der Quellbaum weitere noch nicht kopierte
Knoten enthält (Schritt 2116). Ist dies der Fall, so verzweigt
der Prozess zurück zu 2104, wo ein anderer Knoten zum Kopieren
ausgewählt wird. Andernfalls, wird der Befehl verarbeitet. Auf
diese Weise werden alle Aufrufstack-Baumsegmente zu dem
resultierenden Aufrufstack-Baum hinzugefügt.
Die Vorteile der vorliegenden Erfindung sollten aus der obigen
detaillierten Beschreibung klar hervorgehen. Mit dem oben
beschriebenen Profilierungsansatz wird jede neue periodische
Abtastung als ein unabhängiges Baumsegment behandelt. Wenn der
Job abgeschlossen ist, werden alle Aufrufstack-Baumsegmente in
dem während des gesamten Profilierungsjobs generierte Wald
verschmolzen. Bei der Verschmelzung werden Profilmetriken wie
Basiszeiten als Summe der Basiszeiten der Routinen
aktualisiert. Außerhalb der Abtastperioden, wenn keine
Protokollverarbeitung stattfindet, wird die Systemleistung
kaum beeinträchtigt.
Es kann vorkommen, dass Aufrufstack-Baumsegmente fehlerhaft
verschmolzen werden, weil die Fehlerbehebungsprozedur nicht
garantieren kann, dass die Bildung der Aufrufstack-
Baumsegmente, die höchstwahrscheinlich aufgrund von
entsprechungslosen Ein-/Ausstiegsereignissen am Anfang einer
Abtastperiode Fehler in den Darstellungen von
Ausführungsflüssen enthalten, korrekt erfolgt ist. Es kann
also vorkommen, dass identische Aufrufstack-Bäume, die in
unterschiedlichen Kontexten generiert wurden, kombiniert
werden. Die Gesamtzeit, die in einer bestimmten Methode
aufgewendet werden, ist jedoch innerhalb des abgetasteten
Kontexts, in dem die Zeitwerte generiert wurden, korrekt.
Es ist wichtig zu bedenken, dass die vorliegende Erfindung
hier zwar im Kontext eines voll funktionierenden
Datenverarbeitungssystems beschrieben wurde, dass dem Fachmann
aber klar ist, dass der erfindungsgemäße Prozess auch in Form
eines computerlesbaren Datenträgers mit Instruktionen und in
verschiedenen Formen verteilt werden kann, und dass die
vorliegende Erfindung unabhängig von der jeweiligen Art des
tatsächlich zur Verteilung verwendeten Signalträgers anwendbar
ist. Beispiele für computerlesbare Datenträger sind
beschreibbare Datenträger wie Disketten oder Festplatten, RAM,
und CD-ROMs und Übertragungsmediem wie digitale und analoge
Verbindungen.
Die Beschreibung der vorliegenden Erfindung dient der
Illustration und Erläuterung, soll aber in keiner Weise
erschöpfend oder auf die beschriebene Form beschränkt sein.
Der Fachmann kann sich zahlreiche Abwandlungen vorstellen. Die
Ausführungsform wurde so gewählt und beschrieben, dass die
Prinzipien der Erfindung und die praktische Anwendung am
besten erklärt werden, und dass der durchschnittliche Fachmann
in der Lage ist, die Erfindung für verschiedene
Ausführungsformen mit verschiedenen Abwandlungen zu verstehen,
die für den vorgesehenen Zweck geeignet sind.
Claims (37)
1. Ein Verfahren in einem Datenverarbeitungssystem zur
Profilierung eines im Datenverarbeitungssystem
ausgeführten Programms, wobei das Verfahren folgende
Schritte umfasst:
Durchführung einer auf Abtastung basierenden Profilierung des ausführenden Programms;
für jede Abtastperiode Generierung einer Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen; und
als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, Verschmelzen der Baumdatenstrukturen aller Abtastperioden zu einer resultierenden Baumdatenstruktur.
Durchführung einer auf Abtastung basierenden Profilierung des ausführenden Programms;
für jede Abtastperiode Generierung einer Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen; und
als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, Verschmelzen der Baumdatenstrukturen aller Abtastperioden zu einer resultierenden Baumdatenstruktur.
2. Das System nach Anspruch 1, außerdem umfassend:
die Aufzeichnung ausführungsbezogener Metriken für eine
Abtastperiode in den Knoten der Baumdatenstruktur.
3. Das System nach Anspruch 1, außerdem umfassend:
Aktivierung einer ereignisbasierten Verarbeitung über
eine Zeit, die durch einen ersten vorgegebenen Wert
bestimmt wird.
4. Das System nach Anspruch 3, außerdem umfassend:
als Reaktion darauf, dass während einer Periode, in der die Protokollverarbeitung aktiviert ist, innerhalb einer ausgeführten Routine im Programm ein ausgewähltes Ereignis stattfindet, Aufzeichnung der Protokolldaten einschließlich einer Angabe der ausgeführten Routine; und
Darstellung der resultierenden Routine als Knoten in der Baumdatenstruktur für die Abtastperiode.
als Reaktion darauf, dass während einer Periode, in der die Protokollverarbeitung aktiviert ist, innerhalb einer ausgeführten Routine im Programm ein ausgewähltes Ereignis stattfindet, Aufzeichnung der Protokolldaten einschließlich einer Angabe der ausgeführten Routine; und
Darstellung der resultierenden Routine als Knoten in der Baumdatenstruktur für die Abtastperiode.
5. Das Verfahren nach Anspruch 3, wobei der erste
vorgegebene Wert von einem Benutzer ausgewählt werden
kann.
6. Das Verfahren nach Anspruch 3, wobei der erste
vorgegebene Wert eine Zeitperiode mit Hilfe einer
Zeitmetrik angibt.
7. Das Verfahren nach Anspruch 3, wobei der erste
vorgegebene Wert eine Anzahl von Ereignisvorkommnissen
angibt.
8. Das System nach Anspruch 3, außerdem umfassend:
Aktivierung der Protokollverarbeitung als Reaktion auf
einen ausgewählten Timer-Interrupt.
9. Das System nach Anspruch 1, außerdem umfassend:
Dektivierung einer ereignisbasierten Verarbeitung während
einer Zeit, die durch einen zweiten vorgegebenen Wert
bestimmt wird.
10. Das Verfahren nach Anspruch 9, wobei der zweite
vorgegebene Wert von einem Benutzer ausgewählt werden
kann.
11. Das Verfahren nach Anspruch 9, wobei der zweite
vorgegebene Wert eine Zeitperiode mit Hilfe einer
Zeitmetrik angibt.
12. Das Verfahren nach Anspruch 9, wobei der zweite
vorgegebene Wert eine Anzahl von Ereignisvorkommnissen
angibt.
13. Das System nach Anspruch 1, außerdem umfassend:
die assoziative Verwaltung der Baumdatenstrukturen aus
den Abtastperioden anhand einer Prozess-/Thread-Kennung.
14. Das System nach Anspruch 1, außerdem umfassend:
die Erstellung von Baumdatenstrukturen in Echtzeit bei
der Generierung der Protokolldaten während der Ausführung
des Programms.
15. Das Verfahren nach Anspruch 1, wobei der Schritt der
Verschmelzung von Baumdatenstrukturen außerdem folgende
Schritte umfasst:
Generieren eines Wurzelknotens für eine leere Baumdatenstruktur, die eine endgültige Baumdatenstruktur darstellt;
für jede in einer Abtastperiode generierte Baumdatenstruktur Hinzufügen einer Baumdatenstruktur für eine Abtastperiode zu einer endgültigen Baumdatenstruktur, um eine Vereinigung der Baumdatenstrukturen für eine Abtastperiode mit der endgültigen Baumdatenstruktur herzustellen.
Generieren eines Wurzelknotens für eine leere Baumdatenstruktur, die eine endgültige Baumdatenstruktur darstellt;
für jede in einer Abtastperiode generierte Baumdatenstruktur Hinzufügen einer Baumdatenstruktur für eine Abtastperiode zu einer endgültigen Baumdatenstruktur, um eine Vereinigung der Baumdatenstrukturen für eine Abtastperiode mit der endgültigen Baumdatenstruktur herzustellen.
16. Ein Datenverarbeitungssystem zur Profilierung eines im
Datenverarbeitungssystem ausgeführten Programms, wobei
das Datenverarbeitungssystem folgende Elemente umfasst:
Durchführungsmittel zur auf einer Abtastung basierenden Profilierung des ausgeführten Programms;
ein erstes Generierungsmittel, um für jede Abtastperiode eine Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen, zu erstellen; und
Verschmelzungsmittel, um als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, die Baumdatenstrukturen aller Abtastperioden zu einer resultierenden Baumdatenstruktur zu verschmelzen.
Durchführungsmittel zur auf einer Abtastung basierenden Profilierung des ausgeführten Programms;
ein erstes Generierungsmittel, um für jede Abtastperiode eine Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen, zu erstellen; und
Verschmelzungsmittel, um als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, die Baumdatenstrukturen aller Abtastperioden zu einer resultierenden Baumdatenstruktur zu verschmelzen.
17. Das System nach Anspruch 16, außerdem umfassend:
ein erstes Aufzeichnungsmittel zur Aufzeichnung
ausführungsbezogener Metriken für eine Abtastperiode in
den Knoten der Baumdatenstruktur.
18. Das System nach Anspruch 16, außerdem umfassend:
Aktivierungsmittel zur Aktivierung einer
ereignisbasierten Verarbeitung über eine Zeit, die durch
einen ersten vorgegebenen Wert bestimmt wird.
19. Das System nach Anspruch 18, außerdem umfassend:
ein zweites Aufzeichnungsmittel, um als Reaktion darauf, dass während einer Periode, in der die Protokollverarbeitung aktiviert ist, innerhalb einer ausgeführten Routine im Programm ein ausgewähltes Ereignis stattfindet, Protokolldaten einschließlich einer Angabe der ausgeführten Routine aufzuzeichen; und
ein Darstellungsmittel zur Darstellung der resultierenden Routine als Knoten in der Baumdatenstruktur für die Abtastperiode.
ein zweites Aufzeichnungsmittel, um als Reaktion darauf, dass während einer Periode, in der die Protokollverarbeitung aktiviert ist, innerhalb einer ausgeführten Routine im Programm ein ausgewähltes Ereignis stattfindet, Protokolldaten einschließlich einer Angabe der ausgeführten Routine aufzuzeichen; und
ein Darstellungsmittel zur Darstellung der resultierenden Routine als Knoten in der Baumdatenstruktur für die Abtastperiode.
20. Das Datenverarbeitungssystem nach Anspruch 18, wobei der
erste vorgegebene Wert von einem Benutzer ausgewählt
werden kann.
21. Das Datenverarbeitungssystem nach Anspruch 18, wobei der
erste vorgegebene Wert eine Zeitperiode mit Hilfe einer
Zeitmetrik angibt.
22. Das Datenverarbeitungssystem nach Anspruch 18, wobei der
erste vorgegebene Wert eine Anzahl von
Ereignisvorkommnissen angibt.
23. Das System nach Anspruch 18, außerdem umfassend:
ein Aktivierungsmittel zur Aktivierung der
Protokollverarbeitung als Reaktion auf einen ausgewählten
Timer-Interrupt.
24. Das System nach Anspruch 16, außerdem umfassend:
ein Deaktivierungsmittel zur Dektivierung einer
ereignisbasierten Verarbeitung während einer Zeit, die
durch einen zweiten vorgegebenen Wert bestimmt wird.
25. Das Datenverarbeitungssystem nach Anspruch 24, wobei der
zweite vorgegebene Wert von einem Benutzer ausgewählt
werden kann.
26. Das Datenverarbeitungssystem nach Anspruch 24, wobei der
zweite vorgegebene Wert eine Zeitperiode mit Hilfe einer
Zeitmetrik angibt.
27. Das Datenverarbeitungssystem nach Anspruch 24, wobei der
zweite vorgegebene Wert eine Anzahl von
Ereignisvorkommnissen angibt.
28. Das System nach Anspruch 28, außerdem umfassend:
ein Verwaltungsmittel zur assoziativen Verwaltung der
Baumdatenstrukturen aus dem Abtastperioden anhand einer
Prozess-/Thread-Kennung.
29. Das System nach Anspruch 16, außerdem umfassend:
ein Erstellungsmittel zur Erstellung von
Baumdatenstrukturen in Echtzeit bei der Generierung der
Protokolldaten während der Ausführung des Programms.
30. Das Datenverarbeitungssystem nach Anspruch 16, wobei das
Verschmelzungsmittel zum Verschmelzen der
Baumdatenstrukturen außerdem folgendes umfasst:
ein zweites Generierungsmittel zum Generieren eines Wurzelknotens für eine leere Baumdatenstruktur, die eine endgültige Baumdatenstruktur darstellt; und
ein Hinzufügungsmittel, um für jede in einer Abtastperiode generierte Baumdatenstruktur eine Baumdatenstruktur für eine Abtastperiode zu einer endgültigen Baumdatenstruktur hinzuzufügen, um eine Vereinigung der Baumdatenstrukturen für eine Abtastperiode mit der endgültigen Baumdatenstruktur herzustellen.
ein zweites Generierungsmittel zum Generieren eines Wurzelknotens für eine leere Baumdatenstruktur, die eine endgültige Baumdatenstruktur darstellt; und
ein Hinzufügungsmittel, um für jede in einer Abtastperiode generierte Baumdatenstruktur eine Baumdatenstruktur für eine Abtastperiode zu einer endgültigen Baumdatenstruktur hinzuzufügen, um eine Vereinigung der Baumdatenstrukturen für eine Abtastperiode mit der endgültigen Baumdatenstruktur herzustellen.
31. Ein Computerprogrammprodukt in einem computerlesbaren
Medium zur Verwendung in einem Datenverarbeitungssystem
zur Profilierung eines ausgeführten Programms, wobei das
Computerprogrammprodukt folgendes umfasst:
erste Instruktionen zur Durchführung einer auf Abtastung basierenden Profilierung des ausgeführten Programms;
zweite Instruktionen, um für jede Abtastperiode eine Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen, zu erstellen; und
dritte Instruktionen, um als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, die Baumdatenstrukturen aller Abtastperiode zu einer resultierenden Baumdatenstruktur zu verschmelzen.
erste Instruktionen zur Durchführung einer auf Abtastung basierenden Profilierung des ausgeführten Programms;
zweite Instruktionen, um für jede Abtastperiode eine Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen, zu erstellen; und
dritte Instruktionen, um als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, die Baumdatenstrukturen aller Abtastperiode zu einer resultierenden Baumdatenstruktur zu verschmelzen.
32. Das Computerprogrammprodukt nach Anspruch 31, außerdem
umfassend:
Instruktionen zur Aktivierung einer ereignisbasierten
Verarbeitung über eine Zeit, die durch einen ersten
vorgegebenen Wert bestimmt wird.
33. Das Computerprogrammprodukt nach Anspruch 32, außerdem
umfassend:
Instruktionen, um als Reaktion darauf, dass während einer Periode, in der die Protokollverarbeitung aktiviert ist, innerhalb einer ausgeführte Routine im Programm ein ausgewähltes Ereignis stattfindet, Protokolldaten einschließlich einer Angabe der ausgeführten Routine aufzuzeichnen; und
Instruktionen zur Darstellung der resultierenden Routine als Knoten in der Baumdatenstruktur für die Abtastperiode.
Instruktionen, um als Reaktion darauf, dass während einer Periode, in der die Protokollverarbeitung aktiviert ist, innerhalb einer ausgeführte Routine im Programm ein ausgewähltes Ereignis stattfindet, Protokolldaten einschließlich einer Angabe der ausgeführten Routine aufzuzeichnen; und
Instruktionen zur Darstellung der resultierenden Routine als Knoten in der Baumdatenstruktur für die Abtastperiode.
34. Das Computerprogrammprodukt nach Anspruch 32, außerdem
umfassend:
Instruktionen zur Aktivierung der Protokollverarbeitung
als Reaktion auf einen ausgewählten Timer-Interrupt.
35. Das Computerprogrammprodukt nach Anspruch 31, außerdem
umfassend:
Instruktionen zur Deaktivierung einer ereignisbasierten
Verarbeitung während einer Zeit, die durch einen zweiten
vorgegebenen Wert bestimmt wird.
36. Das Computerprogrammprodukt nach Anspruch 31, außerdem
umfassend:
Instruktionen zur assoziativen Verwaltung der
Baumdatenstrukturen aus dem Abtastperioden anhand einer
Prozess-/Thread-Kennung.
37. Das Computerprogrammprodukt nach Anspruch 31, wobei die
Instruktionen zum Verschmelzen der Baumdatenstrukturen
außerdem folgendes umfassen:
Instruktionen zum Generieren eines Wurzelknotens für eine leere Baumdatenstruktur, die eine endgültige Baumdatenstruktur darstellt;
Instruktionen, um für jede in einer Abtastperiode generierte Baumdatenstruktur eine Baumdatenstruktur für eine Abtastperiode zu einer endgültigen Baumdatenstruktur hinzuzufügen, um eine Vereinigung der Baumdatenstrukturen für eine Abtastperiode mit der endgültigen Baumdatenstruktur herzustellen.
Instruktionen zum Generieren eines Wurzelknotens für eine leere Baumdatenstruktur, die eine endgültige Baumdatenstruktur darstellt;
Instruktionen, um für jede in einer Abtastperiode generierte Baumdatenstruktur eine Baumdatenstruktur für eine Abtastperiode zu einer endgültigen Baumdatenstruktur hinzuzufügen, um eine Vereinigung der Baumdatenstrukturen für eine Abtastperiode mit der endgültigen Baumdatenstruktur herzustellen.
Applications Claiming Priority (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US09/418,379 US6651243B1 (en) | 1997-12-12 | 1999-10-14 | Method and system for periodic trace sampling for real-time generation of segments of call stack trees |
US09/418,379 | 1999-10-14 |
Publications (2)
Publication Number | Publication Date |
---|---|
DE10050684A1 true DE10050684A1 (de) | 2001-04-26 |
DE10050684B4 DE10050684B4 (de) | 2005-12-01 |
Family
ID=23657884
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
DE10050684A Expired - Fee Related DE10050684B4 (de) | 1999-10-14 | 2000-10-13 | Verfahren und System zur periodischen Ablaufverfolgung für Aufrufsequenzen zwischen Routinen |
Country Status (2)
Country | Link |
---|---|
US (1) | US6651243B1 (de) |
DE (1) | DE10050684B4 (de) |
Families Citing this family (88)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6862729B1 (en) * | 2000-04-04 | 2005-03-01 | Microsoft Corporation | Profile-driven data layout optimization |
CA2350735A1 (en) * | 2001-03-14 | 2002-09-14 | Ibm Canada Limited-Ibm Canada Limitee | A method for providing open access to application profiling data |
US20040015860A1 (en) * | 2001-03-15 | 2004-01-22 | International Business Machines Corporation | In the development of computer programs, a method of recording the sequential development of each of a plurality of files forming the program |
US7007268B2 (en) * | 2001-08-20 | 2006-02-28 | Sun Microsystems, Inc. | Method and apparatus for debugging in a massively parallel processing environment |
US20030088853A1 (en) * | 2001-11-07 | 2003-05-08 | Hiromi Iida | Trace information searching device and method therefor |
US7290246B2 (en) * | 2002-04-04 | 2007-10-30 | Texas Instruments Incorporated | Power profiling system and method for correlating runtime information |
US20040003375A1 (en) * | 2002-06-28 | 2004-01-01 | George Jini S. | Method and system for combining dynamic instrumentation and instruction pointer sampling |
US8418145B2 (en) * | 2002-11-07 | 2013-04-09 | Ca, Inc. | Simple method optimization |
US7100151B2 (en) * | 2002-11-22 | 2006-08-29 | Texas Instruments Incorporated | Recovery from corruption using event offset format in data trace |
US7140008B2 (en) * | 2002-11-25 | 2006-11-21 | Microsoft Corporation | Dynamic temporal optimization framework |
US7058936B2 (en) * | 2002-11-25 | 2006-06-06 | Microsoft Corporation | Dynamic prefetching of hot data streams |
US7114150B2 (en) * | 2003-02-13 | 2006-09-26 | International Business Machines Corporation | Apparatus and method for dynamic instrumenting of code to minimize system perturbation |
US7325002B2 (en) | 2003-04-04 | 2008-01-29 | Juniper Networks, Inc. | Detection of network security breaches based on analysis of network record logs |
US20040199913A1 (en) * | 2003-04-07 | 2004-10-07 | Perrow Michael S. | Associative memory model for operating system management |
US7343598B2 (en) * | 2003-04-25 | 2008-03-11 | Microsoft Corporation | Cache-conscious coallocation of hot data streams |
GB0320386D0 (en) * | 2003-08-30 | 2003-10-01 | Ibm | A method, apparatus and computer program for executing a program |
US7587709B2 (en) * | 2003-10-24 | 2009-09-08 | Microsoft Corporation | Adaptive instrumentation runtime monitoring and analysis |
US20050097533A1 (en) * | 2003-10-31 | 2005-05-05 | Chakrabarti Dhruva R. | Run-time performance with call site inline specialization |
US7404178B2 (en) | 2004-02-18 | 2008-07-22 | Hewlett-Packard Development Company, L.P. | ROM-embedded debugging of computer |
US7363615B2 (en) * | 2004-03-12 | 2008-04-22 | Autodesk, Inc. | Stack-based callbacks for diagnostic data generation |
US20050273757A1 (en) * | 2004-06-07 | 2005-12-08 | Anderson Craig D | Methods, systems, and computer program products for summarizing operational behavior of a computer program |
US7971191B2 (en) * | 2004-06-10 | 2011-06-28 | Hewlett-Packard Development Company, L.P. | System and method for analyzing a process |
US8132159B1 (en) | 2004-07-23 | 2012-03-06 | Green Hills Software, Inc. | Post-execution software debugger with event display |
US8136096B1 (en) | 2004-07-23 | 2012-03-13 | Green Hills Software, Inc. | Backward post-execution software debugger |
US8271955B1 (en) | 2004-07-23 | 2012-09-18 | Green Hille Software, Inc. | Forward post-execution software debugger |
US8015552B1 (en) | 2004-07-23 | 2011-09-06 | Green Hills Software, Inc. | Post-execution software debugger with coverage display |
US7653899B1 (en) | 2004-07-23 | 2010-01-26 | Green Hills Software, Inc. | Post-execution software debugger with performance display |
US20060031837A1 (en) * | 2004-08-05 | 2006-02-09 | International Business Machines Corporation | Thread starvation profiler |
US7506320B2 (en) * | 2004-09-09 | 2009-03-17 | International Business Machines Corporation | Generating sequence diagrams using call trees |
US20060130001A1 (en) * | 2004-11-30 | 2006-06-15 | International Business Machines Corporation | Apparatus and method for call stack profiling for a software application |
US7509632B2 (en) * | 2005-03-24 | 2009-03-24 | International Business Machines Corporation | Method and apparatus for analyzing call history data derived from execution of a computer program |
US7607119B2 (en) * | 2005-04-26 | 2009-10-20 | Microsoft Corporation | Variational path profiling |
US7912877B2 (en) | 2005-05-20 | 2011-03-22 | Microsoft Corporation | Leveraging garbage collection to dynamically infer heap invariants |
US7770153B2 (en) * | 2005-05-20 | 2010-08-03 | Microsoft Corporation | Heap-based bug identification using anomaly detection |
US7490098B2 (en) * | 2005-06-10 | 2009-02-10 | International Business Machines Corporation | Apparatus, system, and method for processing hierarchical data in disparate data repositories |
WO2007028227A1 (en) * | 2005-09-09 | 2007-03-15 | Ibm Canada Limited - Ibm Canada Limitee | Integrating different programming language debug tools for observing thread execution |
US20070089094A1 (en) * | 2005-10-13 | 2007-04-19 | Levine Frank E | Temporal sample-based profiling |
US7739675B2 (en) * | 2005-12-16 | 2010-06-15 | International Business Machines Corporation | Dynamically computing a degradation analysis of waiting threads in a virtual machine |
US20070162897A1 (en) * | 2006-01-12 | 2007-07-12 | International Business Machines Corporation | Apparatus and method for profiling based on call stack depth |
US8176480B1 (en) * | 2006-02-27 | 2012-05-08 | Symantec Operating Corporation | Adaptive instrumentation through dynamic recompilation |
US7962901B2 (en) | 2006-04-17 | 2011-06-14 | Microsoft Corporation | Using dynamic analysis to improve model checking |
US7716646B2 (en) * | 2006-05-11 | 2010-05-11 | Rekha Kaushik | Loading a chain of processors from an XML file |
US7937690B2 (en) * | 2006-05-23 | 2011-05-03 | Hewlett-Packard Development Company, L.P. | Evaluating performance of software application |
US7926043B2 (en) * | 2006-06-20 | 2011-04-12 | Microsoft Corporation | Data structure path profiling |
US20080034349A1 (en) * | 2006-08-04 | 2008-02-07 | Microsoft Corporation | Incremental program modification based on usage data |
US7809702B2 (en) * | 2007-05-08 | 2010-10-05 | International Business Machines Corporation | Generating from application modifications commands to modify the objects in a repository |
US8132170B2 (en) * | 2007-08-07 | 2012-03-06 | International Business Machines Corporation | Call stack sampling in a data processing system |
US8056000B2 (en) * | 2007-08-27 | 2011-11-08 | International Business Machines Corporation | Apparatus and system for an automated bidirectional format transform |
US7958154B2 (en) * | 2007-08-29 | 2011-06-07 | International Business Machines Corporation | Apparatus, system, and method for command manager support for pluggable data formats |
US8533683B2 (en) * | 2007-10-15 | 2013-09-10 | Wind River Systems, Inc. | Stack walking enhancements using sensorpoints |
US20090112667A1 (en) * | 2007-10-31 | 2009-04-30 | Ken Blackwell | Automated Business Process Model Discovery |
US8527961B2 (en) * | 2007-11-14 | 2013-09-03 | Oracle America, Inc. | Expression-level debugging without format changes |
US8261245B2 (en) * | 2008-01-22 | 2012-09-04 | International Business Machines Corporation | Method and system for associating profiler data with a reference clock |
US8271956B2 (en) * | 2008-02-07 | 2012-09-18 | International Business Machines Corporation | System, method and program product for dynamically adjusting trace buffer capacity based on execution history |
US8286139B2 (en) * | 2008-03-19 | 2012-10-09 | International Businesss Machines Corporation | Call stack sampling for threads having latencies exceeding a threshold |
US8286134B2 (en) * | 2008-07-15 | 2012-10-09 | International Business Machines Corporation | Call stack sampling for a multi-processor system |
US20100017583A1 (en) * | 2008-07-15 | 2010-01-21 | International Business Machines Corporation | Call Stack Sampling for a Multi-Processor System |
US9418005B2 (en) * | 2008-07-15 | 2016-08-16 | International Business Machines Corporation | Managing garbage collection in a data processing system |
US8566795B2 (en) * | 2008-07-15 | 2013-10-22 | International Business Machines Corporation | Selectively obtaining call stack information based on criteria |
US8024719B2 (en) * | 2008-11-03 | 2011-09-20 | Advanced Micro Devices, Inc. | Bounded hash table sorting in a dynamic program profiling system |
US10230611B2 (en) * | 2009-09-10 | 2019-03-12 | Cisco Technology, Inc. | Dynamic baseline determination for distributed business transaction |
US8938533B1 (en) * | 2009-09-10 | 2015-01-20 | AppDynamics Inc. | Automatic capture of diagnostic data based on transaction behavior learning |
US9167028B1 (en) | 2009-09-10 | 2015-10-20 | AppDynamics, Inc. | Monitoring distributed web application transactions |
US9176783B2 (en) | 2010-05-24 | 2015-11-03 | International Business Machines Corporation | Idle transitions sampling with execution context |
US8843684B2 (en) | 2010-06-11 | 2014-09-23 | International Business Machines Corporation | Performing call stack sampling by setting affinity of target thread to a current process to prevent target thread migration |
US8799872B2 (en) | 2010-06-27 | 2014-08-05 | International Business Machines Corporation | Sampling with sample pacing |
US8510721B2 (en) * | 2010-08-25 | 2013-08-13 | Microsoft Corporation | Dynamic calculation of sample profile reports |
US8595750B2 (en) | 2010-11-30 | 2013-11-26 | Microsoft Corporation | Adaptive tree structure for visualizing data |
US8799904B2 (en) | 2011-01-21 | 2014-08-05 | International Business Machines Corporation | Scalable system call stack sampling |
US8941657B2 (en) | 2011-05-23 | 2015-01-27 | Microsoft Technology Licensing, Llc | Calculating zoom level timeline data |
US8850408B2 (en) * | 2011-08-10 | 2014-09-30 | Nintendo Of America, Inc. | Methods and/or systems for determining a series of return callstacks |
CA2756839C (en) * | 2011-11-02 | 2019-09-10 | Ibm Canada Limited - Ibm Canada Limitee | Programmatic identification of root method |
US9720744B2 (en) | 2011-12-28 | 2017-08-01 | Intel Corporation | Performance monitoring of shared processing resources |
US9311598B1 (en) | 2012-02-02 | 2016-04-12 | AppDynamics, Inc. | Automatic capture of detailed analysis information for web application outliers with very low overhead |
US8793661B1 (en) | 2012-04-27 | 2014-07-29 | Google Inc. | Programmer specified conditions for raising exceptions and handling errors detected within programming code |
US9436588B2 (en) * | 2012-09-28 | 2016-09-06 | Identify Software Ltd. (IL) | Efficient method data recording |
US9098352B2 (en) * | 2013-07-17 | 2015-08-04 | Deja Vu Security, Llc | Metaphor based language fuzzing of computer code |
US9450849B1 (en) * | 2013-07-24 | 2016-09-20 | Amazon Technologies, Inc. | Trace backtracking in distributed systems |
CN111913875B (zh) | 2014-10-24 | 2024-04-26 | 谷歌有限责任公司 | 用于基于软件执行跟踪自动加标签的方法和*** |
US10091076B2 (en) | 2015-08-25 | 2018-10-02 | Google Llc | Systems and methods for configuring a resource for network traffic analysis |
US10031745B2 (en) * | 2016-02-02 | 2018-07-24 | International Business Machines Corporation | System and method for automatic API candidate generation |
US10706101B2 (en) | 2016-04-14 | 2020-07-07 | Advanced Micro Devices, Inc. | Bucketized hash tables with remap entries |
US10140056B2 (en) | 2016-09-27 | 2018-11-27 | Intel Corporation | Systems and methods for differentiating function performance by input parameters |
US10261886B2 (en) | 2016-11-09 | 2019-04-16 | Entit Software Llc | Function call visualization |
US10180894B2 (en) | 2017-06-13 | 2019-01-15 | Microsoft Technology Licensing, Llc | Identifying a stack frame responsible for resource usage |
US10554701B1 (en) | 2018-04-09 | 2020-02-04 | Amazon Technologies, Inc. | Real-time call tracing in a service-oriented system |
US11138094B2 (en) * | 2020-01-10 | 2021-10-05 | International Business Machines Corporation | Creation of minimal working examples and environments for troubleshooting code issues |
US11163592B2 (en) | 2020-01-10 | 2021-11-02 | International Business Machines Corporation | Generation of benchmarks of applications based on performance traces |
Family Cites Families (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5047919A (en) | 1986-04-03 | 1991-09-10 | Harris Corporation | Method and apparatus for monitoring software execution in a parallel multiprocessor computer system |
JP2777496B2 (ja) | 1991-02-28 | 1998-07-16 | インターナショナル・ビジネス・マシーンズ・コーポレイション | コンピュータシステムにおいてマルチプロセスをプロファイリングする際の使用方法 |
US5784554A (en) * | 1993-05-28 | 1998-07-21 | Apple Computer, Inc. | Dynamic sampling profiler |
US5828883A (en) * | 1994-03-31 | 1998-10-27 | Lucent Technologies, Inc. | Call path refinement profiles |
EP0689141A3 (de) | 1994-06-20 | 1997-10-15 | At & T Corp | Unterbrechungsbasierte hardwaremässige Unterstützung für Systemleistungsprofilierung |
US5613118A (en) | 1994-06-20 | 1997-03-18 | International Business Machines Corporation | Profile-based preprocessor for optimizing programs |
US5838976A (en) * | 1995-11-28 | 1998-11-17 | Hewlett-Packard Co. | System and method for profiling code on symmetric multiprocessor architectures |
-
1999
- 1999-10-14 US US09/418,379 patent/US6651243B1/en not_active Expired - Fee Related
-
2000
- 2000-10-13 DE DE10050684A patent/DE10050684B4/de not_active Expired - Fee Related
Also Published As
Publication number | Publication date |
---|---|
US6651243B1 (en) | 2003-11-18 |
DE10050684B4 (de) | 2005-12-01 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
DE10050684B4 (de) | Verfahren und System zur periodischen Ablaufverfolgung für Aufrufsequenzen zwischen Routinen | |
DE60130840T2 (de) | Vorrichtung und Verfahren zur Katalogisierung von symbolischen Daten zur Verwendung bei der Leistungsanalyse von Computerprogrammen | |
DE112017006806T5 (de) | Datenflussverzögerungen in einer daten-streaming-anwendung verringern | |
DE69712678T3 (de) | Verfahren zur Echtzeitüberwachung eines Rechnersystems zu seiner Verwaltung und Hilfe zu seiner Wartung während seiner Betriebsbereitschaft | |
DE69909945T2 (de) | Verfahren und Anordnung zur Korrelation von Profildaten dynamisch erzeugt durch ein optimiertes ausführbares Programm mit Quellcodeanweisungen | |
DE112012000797B4 (de) | Mehrfach-Modellierungsparadigma für eine Vorhersageanalytik | |
DE69909021T2 (de) | Dynamische Speicherrückforderung ohne Compiler- oder Programmverbinderunterstützung | |
DE4332993C1 (de) | Tracer-System zur Fehleranalyse in laufenden Realzeitsystemen | |
DE69919632T2 (de) | Fehlertoleranz durch N-modulare Softwareredundanz unter Verwendung von indirekter Instrumentierung | |
DE69819849T2 (de) | Anordnung zum willkürlichen Abtasten von Instruktionen in einer Prozessorpipeline | |
DE60017457T2 (de) | Verfahren zur isolierung eines fehlers in fehlernachrichten | |
DE69913375T2 (de) | Anzeige eines fehlers in einem transaktionsverarbeitungssystem | |
DE60314742T2 (de) | System und verfahren zur überwachung eines computers | |
DE10393481T5 (de) | Verfahren und Vorrichtung zum Durchführen einer Cache-Umgehung | |
EP1097428A2 (de) | System und verfahren zum prüfen von netzwerk-anwendungen | |
DE4011745A1 (de) | Taskverfolgungseinrichtung | |
DE102014116367A1 (de) | Verwaltung von leistungsstufen von informationstechnologiesystemen | |
DE10039538A1 (de) | Vorrichtung und Methode zum Analysieren der Leistung eines Computerprogramms | |
DE112011101759B4 (de) | Sampling von Leerlauftransitionen | |
DE102007046947A1 (de) | System und Verfahren zum Verwalten von Systemmanagement-Interrupts in einem Mehrprozessor-Computersystem | |
DE202017106569U1 (de) | Analyse grossangelegter Datenverarbeitungsaufträge | |
DE10228779A1 (de) | System und Verfahren zum Umwandeln von Prüfdaten eines Betriebssystems in ein gewünschtes Format | |
DE112011100168B4 (de) | Erfassen von Diagnosedaten in einer Datenverarbeitungsumgebung | |
EP0721620B1 (de) | Tracer-system zur fehleranalyse in laufenden realzeitsystemen | |
DE102016103019A1 (de) | Hardwaregestützte Kantenprofilerstellung |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
OP8 | Request for examination as to paragraph 44 patent law | ||
8364 | No opposition during term of opposition | ||
8339 | Ceased/non-payment of the annual fee |