DE10050684B4 - Verfahren und System zur periodischen Ablaufverfolgung für Aufrufsequenzen zwischen Routinen - Google Patents

Verfahren und System zur periodischen Ablaufverfolgung für Aufrufsequenzen zwischen Routinen Download PDF

Info

Publication number
DE10050684B4
DE10050684B4 DE10050684A DE10050684A DE10050684B4 DE 10050684 B4 DE10050684 B4 DE 10050684B4 DE 10050684 A DE10050684 A DE 10050684A DE 10050684 A DE10050684 A DE 10050684A DE 10050684 B4 DE10050684 B4 DE 10050684B4
Authority
DE
Germany
Prior art keywords
tree
program
processing system
routine
data processing
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.)
Expired - Fee Related
Application number
DE10050684A
Other languages
English (en)
Other versions
DE10050684A1 (de
Inventor
Robert Francis Austin Berry
Frank Eliot Austin Levine
Robert J. Austin Urquhart
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
International Business Machines Corp
Original Assignee
International Business Machines Corp
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by International Business Machines Corp filed Critical International Business Machines Corp
Publication of DE10050684A1 publication Critical patent/DE10050684A1/de
Application granted granted Critical
Publication of DE10050684B4 publication Critical patent/DE10050684B4/de
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/30Monitoring
    • G06F11/34Recording 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/3409Recording 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/3419Recording 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
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/30Monitoring
    • G06F11/34Recording 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/3466Performance evaluation by tracing or monitoring
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2201/00Indexing scheme relating to error detection, to error correction, and to monitoring
    • G06F2201/835Timestamp
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2201/00Indexing scheme relating to error detection, to error correction, and to monitoring
    • G06F2201/86Event-based monitoring
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2201/00Indexing scheme relating to error detection, to error correction, and to monitoring
    • G06F2201/88Monitoring involving counting
    • YGENERAL 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
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02DCLIMATE 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/00Energy efficient computing, e.g. low power processors, power management or thermal management

Abstract

Ein Verfahren in einem Datenverarbeitungssystem zur Profilierung eines im Datenverarbeitungssystem ausgeführten Programms mit einer Vielzahl ausführbarer Routinen, wobei das Verfahren folgende Schritte umfasst:
Durchführung einer auf Abtastung basierenden Profilierung des ausführenden Programms, wobei die Abtastung nicht kontinuierlich sondern in automatisch aktivierten Abtastperioden erfolgt;
für jede, Abtastperiode Generierung einer Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen und welche die Aufrufsequenzen der Routinen zur Laufzeit des Programms erfasst und zur Baumdatenstruktur zusammenführt; und
als Reaktion auf die Feststellung, dass die Ausführung des Programms abgeschlossen ist, Verschmelzen der Baumdatenstrukturen aller Abtastperioden zu einer resultierenden Baumdatenstruktur.

Description

  • HINTERGRUND DER ERFINDUNG
  • Die vorliegende Erfindung betrifft ein verbessertes Datenverarbeitungssystem und speziell ein Verfahren 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.
  • In wiederum anderen Ansätzen, wie etwa der Lehre gemäß dem US Patent US 5,838,976 , geht es um die Korrektheit der Leistungsermittlung bei der Ausführung eines Programmes auf einem Multiprozessor-Systems unter dem Gesichtpunkt der Parallelverarbeitung. Gemäß dieser Lehre soll verhindert werden, dass sich sog. "symmetrically executing code", der gleichzeitig auf unterschiedlichen CPUs ausgeführt wird, mehrfach auf die gesamte Ausführungszeit durchschlägt und diese dadurch verfälscht.
  • 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. Insbesondere soll das Problem gelöst werden mittels einer Profilierung zu ermitteln, wie und in welcher Häufigkeit sich die einzelnen Routinen (dh Funktionen) wechselseitig aufrufen, aus denen sich ein Programm zusammensetzt, ums so die Aufrufcharakteristik innerhalb eines Programmes zu bestimmen.
  • ÜBERBLICK ÜBER DIE ERFINDUNG
  • 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. Aus dieser resultierenden Baumdatenstruktur ergibt sich schließlich, wie und in welcher Häufigkeit sich die einzelnen Routinen (dh Funktionen) wechselseitig aufrufen, aus denen sich ein Programm zusammensetzt.
  • 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:
  • 1 zeigt ein verteiltes Datenverarbeitungssystem, in dem die vorliegende Erfindung eingesetzt werden kann;
  • Die 2A2B sind Blockdiagramme, in denen ein Datenverarbeitungssystem dargestellt ist, in dem die vorliegende Erfindung implementiert werden kann;
  • 3A ist ein Blockdiagramm, in dem die Beziehung zwischen den Software-Komponenten in einem Computersystem, in dem die vorliegende Erfindung implementiert ist, aufgezeigt wird.
  • 3B ist ein Blockdiagramm, in dem eine virtuelle Java-Maschine gemäß einer bevorzugten Ausführungsform der vorliegenden Erfindung dargestellt ist;
  • 4 ist ein Blockdiagramm, in dem die Komponenten dargestellt sind, die zur Profilierung von Prozessen in einem Datenverarbeitungssystem verwendet werden.
  • 5 ist eine Zeichnung, in der verschiedene Phasen bei der Profilierung des aktiven Prozesses in einem Betriebssystem dargestellt werden;
  • 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;
  • 7 ist ein Flussdiagramm eines Prozesses, der in einem Systeminterrupt-Handler-Protokollanker verwendet wird;
  • 8 ist ein Diagramm, in dem der Aufrufstack, der Stack Frames enthält, dargestellt ist;
  • 9 zeigt ein Beispiel für einen Aufrufstack;
  • 10A zeigt eine Programmausführungssequenz zusammen mit dem Zustand des Aufrufstack an jedem Funktionseinstiegs- und Funktionsausstiegspunkt.
  • 10B zeigt eine bestimmte zeitperiodenbasierte Abtastung des in 10A dargestellten Ausführungsflusses;
  • Die 10C und 10D sind Zeitdiagramme, die ein Beispiel der vom Profilierungs-Tool berücksichtigten Zeittypen zeigen;
  • 11A ist ein Diagramm, in dem eine aus der Abtastung von Aufrufstacks generierte Baumstruktur dargestellt ist;
  • 11B ist ein Diagramm, das einen Ereignisbaum zeigt, der die bei der Systemausführung beobachteten Aufrufstacks widerspiegelt.
  • 12 ist eine tabellarische Darstellung eines Aufrufstacks;
  • 13 ist ein Flussdiagramm, in dem ein Verfahren zur Erstellung eines Aufrufstack-Baums mit Hilfe einer Ablaufprotokoll-Textdatei als Eingabedatei dargestellt ist;
  • 14 ist ein Flussdiagramm, in dem ein Verfahren zur dynamischen Erstellung eines Aufrufstack-Baums bei der Abtastung während der Systemausführung dargestellt ist;
  • 15 zeigt einen Datensatz, der mit Hilfe der erfindungsgemäßen Prozesse generiert wurde;
  • 16 zeigt eine andere Berichtsart, die erzeugt werden kann, um die Aufrufstruktur zwischen den in 12 dargestellten Routinen aufzuzeigen;
  • 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.
  • 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;
  • 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;
  • 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
  • 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.
  • AUSFÜHRLICHE BESCHREIBUNG DER BEVORZUGTEN AUSFÜHRUNGSFORMEN
  • In den Zeichnungen, und speziell in 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 108112. 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.
  • 1 ist als Beispiel zu verstehen, nicht als Einschränkung der Netzwerkarchitektur für die erfindungsgemäßen Prozesse.
  • In 2A ist ein Blockdiagramm eines Datenverarbeitungssystems dargestellt, das im Rahmen der Erfindung als Server wie z.B. Server 104 in 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 auch 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 108112 in 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 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 2A abgebildete Datenverarbeitungssystem kann beispielsweise ein RISC/System 6000 sein, auf dem das Betriebssystem AIX (Advanced Interactive Executive) läuft. In 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 2B koordiniert und steuert. Das Betriebssystem kann ein handelsübliches Betriebssystem wie Java-OS For Business oder OS/2 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 2B dargestellte Hardware je nach Implementierung unterschiedlich aussehen kann. So können zum Beispiel zusätzlich zu der in 2B dargestellten Hardware oder anstelle der in 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.
  • 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 Datenverarbeitungssstemen 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. 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.
  • 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 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.
  • 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. 6 zeigt weitere Details über die Generierung von Protokolldatensätzen, auf die im Zusammenhang mit 5 nicht eingegangen wurde.
  • Protokolldatensätze können durch Ausführung kleiner Codestücke, den sogenannten "Ankern" hooks 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 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 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 8 und 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 Darstelllung 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 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 802808 befinden sich die EIPs 802b808b, 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 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 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 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 8 nicht dargestellt), EIP 808b, EIP 806b, EIP 804b und EIP 802b. In 9 ist pcv = addr1, EIP 808b = addr2, EIP 806b = addr3, EIP 804b = addr4, EIP 802b = addr5.
  • 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 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 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 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 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 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 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 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 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 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 11B ausführlicher eingegangen. Wenn in 10C 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.
  • 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 11021108 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 Zeiger 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 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 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 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 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 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 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 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 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 12.
  • In 12 wird nun ein Aufrufstack-Baum in Tabellenform beschrieben. 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 11B kann dynamisch an Ort und Stelle oder statisch mit einer Protokolldatei als Eingabe erstellt werden. 13 ist ein Flussdiagramm, in dem ein Verfahren zur Erstellung eines Aufrufstack-Baums mit Hilfe einer Protokolltextdatei als Eingabedatei dargestellt ist. In 13 wird der Aufrufstack-Baum aufgebaut, um Moduleinstiegs- und Modulausstiegspunkte aufzuzeigen.
  • In 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).
  • 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 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 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 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 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.
  • 15 ist ein Diagramm eines mit dem erfindungsgemäßen Verfahren erzeugten Datensatzes. In 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 16 ist ein Diagramm einer anderen Berichtsart, die erstellt werden kann, dargestellt. Der in 16 dargestellte Bericht zeigt im wesentlichen die gleichen Informationen wie 15, aber in einem etwas anderen Format. Wie bei 15 enthält ein Diagramm 1600 Informationen über Aufrufe, Basiszeit und kumulative Zeit. In 16 ist eine Protokollausgabe zu sehen, in der die in verschiedenen Routinen aufgewendeten Zeiten in Millisekunden angegeben sind. 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 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 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 17 ist ein Bericht dargestellt, der aus einer Protokolldatei generiert wurde, die sowohl ereignisbasierte Profilierungsdaten wie Methodeneinstiege und Methodenausstiege als auch Stack-Aufrollinformationen aus der auf Abtastung basierenden Profilierung enthält. 17 entspricht im wesentlichen 12, wo ein Aufrufstack-Baum als Bericht dargestellt ist, wobei 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.
  • 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 18 zu sehen ist, wird beispielsweise der Untercode für eine Stackaufrollung mit 0 × 7fffffff bezeichnet und kann für zwei verschiedene Zwecke eingesetzt werden. Der erste Zweck, hier mit dem Hauptcode 0 × 40 bezeichnet, ist die Stackaufrollung bei einem Timer-Interrupt. Der zweite Zweck, hier mit dem Hauptcode 0 × 41 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 0 × 50. 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 0 × 30 einen Profilierungszweck der Instrumentierung von interpretierten Methoden, während ein Untercode mit den gleichen Werten einen Methodenaufruf oder das Verlassen einer Methode signalisiert.
  • In 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 17 dargestellten generierten Bericht ist zu sehen, dass die Stackaufrollkennungen den Wert 0 × 40 haben, was nach der Tabelle in 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 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 0 × 41 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 11A und 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.
  • 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 19 dargestellte Prozess Schritt 1478 in 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 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 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.
  • 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.
  • 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 wird, 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.

Claims (32)

  1. Ein Verfahren in einem Datenverarbeitungssystem zur Profilierung eines im Datenverarbeitungssystem ausgeführten Programms mit einer Vielzahl ausführbarer Routinen, wobei das Verfahren folgende Schritte umfasst: Durchführung einer auf Abtastung basierenden Profilierung des ausführenden Programms, wobei die Abtastung nicht kontinuierlich sondern in automatisch aktivierten Abtastperioden erfolgt; für jede, Abtastperiode Generierung einer Baumdatenstruktur, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen und welche die Aufrufsequenzen der Routinen zur Laufzeit des Programms erfasst und zur Baumdatenstruktur zusammenführt; 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 verfahren nach Anspruch 1, außerdem umfassend: die Aufzeichnung ausführungsbezogener Metriken für eine Abtastperiode in den Knoten der Baumdatenstruktur.
  3. Das Verfahren nach Anspruch 1, außerdem umfassend: Aktivierung einer ereignisbasierten Abtastung für die Dauer der Abtastung, die durch einen ersten vorgegebenen Wert bestimmt wird; und als Ereignis die Einstiege und/oder Ausstiege in/aus den ausgeführten Routinen gewählt werden.
  4. Das Verfahren 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.
  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 die Dauer der Abtastperiode durch die Zahl der pro Abtastperiode zu profilierenden Ereignisse spezifiziert.
  8. Das Verfahren nach Anspruch 3, außerdem umfassend: automatische Aktivierung der Profilierung für jede Abtastperiode als Reaktion auf einen ausgewählten Timer-Interrupt.
  9. Das verfahren nach Anspruch 1, außerdem umfassend: Deaktivierung der Profilierung während einer Zeitdauer, 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, während dessen keine Profilierung erfolgt.
  13. Das Verfahren nach Anspruch 1, außerdem umfassend: die assoziative Verwaltung der Baumdatenstrukturen aus den Abtastperioden anhand einer Prozess-/Thread-Kennung.
  14. Das Verfahren 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 die resultierende Baumdatenstruktur iterativ generiert wird, indem der dem Wurzelkoten einer Baumstruktur einer bestimmten Abtastperiode entsprechende Knoten in der resultierenden Baumdatenstruktur bestimmt wird und über diesen entsprechenden Konten mit der resultierenden Baumdatenstruktur verschmolzen wird.
  16. Ein Datenverarbeitungssystem zur Profilierung eines im Datenverarbeitungssystem ausgeführten Programms mit einer Vielzahl ausführbarer Routinen, wobei das Datenverarbeitungssystem folgende Elemente umfasst: Durchführungsmittel zur auf einer Abtastung basierenden Profilierung des ausgeführten Programms, wobei die Abtastung nicht kontinuierlich sondern in automatisch aktivierten Abtastperioden erfolgt; ein erstes Generierungsmittel, um für jede Abtastperiode eine Baumdatenstruktur zu erstellen, in der Knoten der Baumdatenstruktur Routinen des während der Abtastperiode ausgeführten Programms darstellen und in der die Aufrufsequenzen der Routinen zur Laufzeit des Programms erfasst und zur Baumdatenstruktur zusammengeführt sind; 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 Datenverarbeitungssystem 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 Datenverarbeitungssystem nach Anspruch 16, außerdem umfassend: Aktivierungsmittel zur Aktivierung einer ereignisbasierten Verarbeitung für die Dauer der Abtastung, die durch einen ersten vorgegebenen Wert bestimmt wird; und wobei die Aktivierungsmittel als Ereignis die Einstiege und/oder Ausstiege in/aus den ausgeführten Routinen wählen.
  19. Das Datenverarbeitungssystem 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.
  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 die Dauer der Abtastperiode durch die Zahl der pro Abtastperiode zu profilierenden Ereignisse spezifiziert.
  23. Das Datenverarbeitungssystem nach Anspruch 18, außerdem umfassend: ein Aktivierungsmittel automatische Aktivierung der Profilierung für jede Abtastperiode als Reaktion auf einen ausgewählten Timer-Interrupt.
  24. Das Datenverarbeitungssystem nach Anspruch 16, außerdem umfassend: ein Deaktivierungsmittel zur Deaktivierung der Profilierung während einer Zeitdauer, 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, während dessen keine Profilierung erfolgt.
  28. Das Datenverarbeitungssystem nach Anspruch 16, außerdem umfassend: ein Verwaltungsmittel zur assoziativen Verwaltung der Baumdatenstrukturen aus den Abtastperioden anhand einer Prozess-/Thread-Kennung.
  29. Das Datenverarbeitungssystem 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 Hinzufügungsmittel zur iterativen Generierung der resultierende Baumdatenstruktur, indem der dem Wurzelkoten einer Baumstruktur einer bestimmten Abtastperiode entsprechende Knoten in der resultierenden Baumdatenstruktur bestimmt wird und über diesen entsprechenden Konten mit der resultierenden Baumdatenstruktur verschmolzen wird.
  31. Computerprogramm für die Ausführung in einem Datenverarbeitungssystem, enthaltend Codeabschnitte zum Ausführen entsprechender Schritte des Verfahrens nach einem der Ansprüche 1 bis 15, wenn es zur Ausführung geladen wird.
  32. Datenträger, auf dem das Computerprogramm gemäß Patentanspruch 31 gespeichert ist.
DE10050684A 1999-10-14 2000-10-13 Verfahren und System zur periodischen Ablaufverfolgung für Aufrufsequenzen zwischen Routinen Expired - Fee Related DE10050684B4 (de)

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 DE10050684A1 (de) 2001-04-26
DE10050684B4 true 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)

* Cited by examiner, † Cited by third party
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
US7058936B2 (en) * 2002-11-25 2006-06-06 Microsoft Corporation Dynamic prefetching of hot data streams
US7140008B2 (en) * 2002-11-25 2006-11-21 Microsoft Corporation Dynamic temporal optimization framework
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
US8015552B1 (en) 2004-07-23 2011-09-06 Green Hills Software, Inc. Post-execution software debugger with coverage 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
US8132159B1 (en) 2004-07-23 2012-03-06 Green Hills Software, Inc. Post-execution software debugger with event 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
US9418005B2 (en) * 2008-07-15 2016-08-16 International Business Machines Corporation Managing garbage collection in a data processing system
US8286134B2 (en) * 2008-07-15 2012-10-09 International Business Machines Corporation Call stack sampling for a multi-processor system
US8566795B2 (en) * 2008-07-15 2013-10-22 International Business Machines Corporation Selectively obtaining call stack information based on criteria
US20100017583A1 (en) * 2008-07-15 2010-01-21 International Business Machines Corporation Call Stack Sampling for a Multi-Processor System
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
US9167028B1 (en) * 2009-09-10 2015-10-20 AppDynamics, Inc. Monitoring distributed web application transactions
US8938533B1 (en) * 2009-09-10 2015-01-20 AppDynamics Inc. Automatic capture of diagnostic data based on transaction behavior learning
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
WO2016061820A1 (en) 2014-10-24 2016-04-28 Google Inc. Methods and systems for automated tagging based on software execution traces
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

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5838976A (en) * 1995-11-28 1998-11-17 Hewlett-Packard Co. System and method for profiling code on symmetric multiprocessor architectures

Family Cites Families (6)

* Cited by examiner, † Cited by third party
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
US5613118A (en) 1994-06-20 1997-03-18 International Business Machines Corporation Profile-based preprocessor for optimizing programs
EP0689141A3 (de) 1994-06-20 1997-10-15 At & T Corp Unterbrechungsbasierte hardwaremässige Unterstützung für Systemleistungsprofilierung

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5838976A (en) * 1995-11-28 1998-11-17 Hewlett-Packard Co. System and method for profiling code on symmetric multiprocessor architectures

Also Published As

Publication number Publication date
US6651243B1 (en) 2003-11-18
DE10050684A1 (de) 2001-04-26

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
US6728949B1 (en) Method and system for periodic trace sampling using a mask to qualify trace data
DE69834230T2 (de) Verfahren und Gerät zur Optimierung des Programmablaufs von Anwendungen
DE69909021T2 (de) Dynamische Speicherrückforderung ohne Compiler- oder Programmverbinderunterstützung
US6055492A (en) System and method for providing trace information data reduction
US6338159B1 (en) System and method for providing trace information
DE112017006806T5 (de) Datenflussverzögerungen in einer daten-streaming-anwendung verringern
US6349406B1 (en) Method and system for compensating for instrumentation overhead in trace data by computing average minimum event times
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
US6507805B1 (en) Method and system for compensating for instrumentation overhead in trace data by detecting minimum event times
DE60032694T2 (de) Speicherrückforderungsverfahren
DE4332993C1 (de) Tracer-System zur Fehleranalyse in laufenden Realzeitsystemen
DE69911266T2 (de) Computerprogrammprofiler
DE69938218T2 (de) Vorrichtung und Verfahren zum Laden eines Java Anwendungsprogramms
US6539339B1 (en) Method and system for maintaining thread-relative metrics for trace data adjusted for thread switches
DE4108590C2 (de) Verfahren zum Benchmark-Testen der Arbeitsgeschwindigkeit eines Computersystem
US6604210B1 (en) Method and system for detecting and recovering from in trace data
DE10240883A1 (de) Verfahren zum Erfassen eines unbegrenzten Wachstums verketteter Listen in einer laufenden Anwendung
DE10393481T5 (de) Verfahren und Vorrichtung zum Durchführen einer Cache-Umgehung
WO1994014117A1 (de) Verfahren zum testen mindestens einer klasse eines objektorientierten programmes auf einem rechner
DE60314742T2 (de) System und verfahren zur überwachung eines computers
DE112011101759B4 (de) Sampling von Leerlauftransitionen
DE10228779A1 (de) System und Verfahren zum Umwandeln von Prüfdaten eines Betriebssystems in ein gewünschtes Format

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