Lors de l'instrumentation du système en vue de répondre aux questions portant sur les problèmes de performance, il est utile d'envisager comment le groupement de données permet de répondre à une question spécifique, plutôt que de raisonner en termes de rassemblement de données par des sondes individuelles. Par exemple, si vous souhaitez connaître le nombre d'appels système par ID utilisateur, vous n'avez pas nécessairement besoin de connaître les données recueillies au niveau de chaque appel système. Seule la consultation d'un tableau des ID utilisateur et des appels système présente pour vous un intérêt. Auparavant, pour répondre à cette question, vous deviez rassembler les données obtenues au niveau de chaque appel système pour procéder ensuite au post-traitement des données à l'aide d'un outil comme awk(1) ou perl(1). Cependant, dans DTrace, le groupement de données constitue une opération de première classe. Ce chapitre décrit les fonctions de DTrace permettant de manipuler les groupements.
Une fonction de groupement se caractérise par les propriétés suivantes :
f(f(x0) U f(x 1) U ... U f(xn)) = f(x 0 U x1 U ... U xn)
où xn est un jeu de données arbitraires. En bref, appliquer une fonction de groupement à des sous-ensembles puis la réappliquer aux résultats obtenus revient à l'appliquer à l'intégralité des données. Par exemple, prenons une fonction SUM permettant d'additionner un jeu de données. Si les données brutes se composent des éléments {2, 1, 2, 5, 4, 3, 6, 4, 2}, on obtient {29} en appliquant la fonction SUM à l'intégralité du jeu. De la même façon, l'application de SUM au sous-ensemble comprenant les trois premiers éléments donne comme résultat {5}, l'application de SUM à l'ensemble comprenant les trois éléments suivants donne comme résultat {12} et l'application de SUM aux trois éléments restants donne également comme résultat {12}. SUM est une fonction de groupement car son application à l'ensemble formé par les résultats {5, 12, 12} donne le même résultat, {29}, que l'application de SUM aux données d'origine.
Toutes les fonctions ne sont pas des fonctions de groupement. C'est notamment le cas de la fonction MEDIAN : elle détermine la valeur médiane d'un jeu de données. (La médiane se caractérise comme l'élément d'un ensemble ayant une valeur telle qu'il existe autant d'éléments dont la valeur est supérieure à la sienne que d'éléments dont la valeur est inférieure à la sienne.) La fonction MEDIAN est calculée en triant l'ensemble et en sélectionnant l'élément central. Si l'on revient aux données brutes d'origine, l'application de la fonction MEDIAN à l'ensemble comprenant les trois premiers éléments donne comme résultat {2}. (L'ensemble trié donne {1, 2, 2} ; {2} constitue l'élément central de l'ensemble.) De même, l'application de la fonction MEDIAN aux trois éléments suivants donne comme résultat {4} et son application aux trois derniers éléments donne comme résultat {4}. L'application de MEDIAN à chacun des sous-ensembles donne donc {2, 4, 4}. Le résultat donné par l'application de MEDIAN à cet ensemble est {4}. Toutefois, le tri de l'ensemble d'origine donne comme résultat {1, 2, 2, 2, 3, 4, 4, 5, 6}. L'application de MEDIAN à cet ensemble donne donc comme résultat {3}. Étant donné que les résultats ne correspondent pas, MEDIAN n'est pas une fonction de groupement.
De nombreuses fonctions courantes permettant d'interpréter un jeu de données sont des fonctions de groupement. Ces fonctions permettent entre autres de compter le nombre d'éléments dans un ensemble, de calculer les valeurs minimale et maximale d'un ensemble et d'additionner l'ensemble des éléments au sein de cet ensemble. Il est possible de déterminer la signification arithmétique à partir de la fonction permettant de compter le nombre d'éléments dans l'ensemble et celle permettant d'additionner le nombre d'éléments dans l'ensemble.
Toutefois, plusieurs fonctions utiles ne sont pas des fonctions de groupement, comme par exemple les fonctions permettant de calculer le mode (l'élément le plus courant) d'un ensemble, sa valeur médiane ou son écart type.
L'application de fonctions de groupement à des données alors qu'elles font l'objet d'un suivi présente de nombreux avantages :
Il n'est pas nécessaire de stocker l'intégralité des données. Lorsqu'un nouvel élément doit être ajouté à l'ensemble, la fonction de groupement est calculée en fonction de l'ensemble comprenant le résultat intermédiaire actuel et le nouvel élément. Après le calcul du nouveau résultat, le nouvel élément peut être ignoré. Ce processus réduit la quantité de stockage requise par un facteur du nombre de points de données, souvent très élevé.
La collection de données ne provoque pas de problèmes d'évolutivité pathologiques. Les fonctions de groupement permettent de conserver les résultats intermédiaires par CPU plutôt que dans une structure de données partagées. DTrace applique ensuite la fonction de groupement à l'ensemble comprenant les résultats intermédiaires par CPU pour produire le résultat final à l'échelle du système.
DTrace stocke les résultats des fonctions de groupement dans des objets appelés groupements. Les résultats des groupements sont indexés avec un tuple d'expressions similaires à celles utilisées pour les tableaux associatifs. En D, la syntaxe d'un groupement est la suivante :
@name[ keys ] = aggfunc ( args );
où name est le nom du groupement, keys est une liste d'expressions D, séparées par des virgules, aggfunc est l'une des fonctions de groupement DTrace et args est une liste d'arguments séparés par des virgules, correspondant à la fonction de groupement. Le groupement nameest un identificateur D ayant comme préfixe le caractère spécial @. Tous les groupements de vos programmes D sont des variables globales ; il n'existe pas de groupement local de clause ou de thread. Les noms de groupement sont conservés dans un espace de noms d'identificateurs séparé des autres variables globales D. N'oubliez pas que a et @a ne sont pas la même variable si vous réutilisez les noms. Le nom de groupement spécial @ peut être utilisé pour nommer un groupement anonyme avec des programmes D simples. Le compilateur D traite ce nom en tant qu'alias du nom de groupement @_.
Les fonctions de groupement DTrace sont affichées dans le tableau suivant. La plupart des fonctions de groupement ne prennent qu'un seul argument représentant la nouvelle donnée.
Tableau 9–1 Fonctions de groupement DTrace
Nom de la fonction |
Arguments |
Résultat |
---|---|---|
count |
aucun |
Nombre d'appels. |
sum |
expression scalaire |
Valeur totale des expressions spécifiées. |
avg |
expression scalaire |
Moyenne arithmétique des expressions spécifiées. |
min |
expression scalaire |
Valeur la plus faible parmi les expressions spécifiées. |
max |
expression scalaire |
Valeur la plus élevée parmi les expressions spécifiées. |
lquantize |
expression scalaire, limite inférieure, limite supérieure, valeur d'étape |
Répartition linéaire des fréquences, comprises dans la plage spécifiée, des valeurs des expressions spécifiées. Incrémente la valeur dans le compartiment inférieur le plus proche de l'expression spécifiée. |
quantize |
expression scalaire |
Répartition des fréquences multiples de deux des valeurs des expressions spécifiées. Incrémente la valeur dans le compartiment multiple de deux inférieur le plus proche de l'expression spécifiée. |
Par exemple, pour compter le nombre d'appels système write(2) dans le système, vous pouvez utiliser une chaîne informative en tant que clé ainsi que la fonction de groupement count() :
syscall::write:entry { @counts["write system calls"] = count(); }
La commande dtrace affiche les résultats du groupement par défaut lorsque le processus se termine, soit en tant que résultat d'une action explicite END, soit lorsque l'utilisateur appuie sur Control-C. L'exemple de sortie suivant montre le résultat de l'exécution de cette commande, après une attente de quelques secondes et après avoir appuyé sur Control-C :
# dtrace -s writes.d dtrace: script './writes.d' matched 1 probe ^C write system calls 179 # |
Vous pouvez compter les appels système par nom de processus en utilisant la variable execname en tant que clé à un groupement :
syscall::write:entry { @counts[execname] = count(); }
L'exemple de sortie suivant montre le résultat de l'exécution de cette commande, après une attente de quelques secondes et après avoir appuyé sur Control-C :
# dtrace -s writesbycmd.d dtrace: script './writesbycmd.d' matched 1 probe ^C dtrace 1 cat 4 sed 9 head 9 grep 14 find 15 tail 25 mountd 28 expr 72 sh 291 tee 814 def.dir.flp 1996 make.bin 2010 # |
Vous pouvez également vouloir examiner de manière plus approfondie les saisies, organisées par nom exécutable et descripteur de fichier. Le descripteur de fichier est le premier argument de write(2) ; l'exemple suivant utilise donc une clé comprenant à la fois execname et arg0 :
syscall::write:entry { @counts[execname, arg0] = count(); }
L'exécution de cette commande génère un tableau comprenant le nom exécutable et le descripteur de fichier, comme illustré dans l'exemple suivant :
# dtrace -s writesbycmdfd.d dtrace: script './writesbycmdfd.d' matched 1 probe ^C cat 1 58 sed 1 60 grep 1 89 tee 1 156 tee 3 156 make.bin 5 164 acomp 1 263 macrogen 4 286 cg 1 397 acomp 3 736 make.bin 1 880 iropt 4 1731 # |
L'exemple suivant affiche le temps moyen écoulé lors de l'appel système en écriture, par nom de processus. Cet exemple utilise la fonction de groupement avg(), en spécifiant l'expression sur laquelle effectuer le calcul de la moyenne en tant qu'argument. L'exemple fait la moyenne du temps écoulé dans l'appel système :
syscall::write:entry { self->ts = timestamp; } syscall::write:return /self->ts/ { @time[execname] = avg(timestamp - self->ts); self->ts = 0; }
L'exemple de sortie suivant montre le résultat de l'exécution de cette commande, après une attente de quelques secondes et après avoir appuyé sur Control-C :
# dtrace -s writetime.d dtrace: script './writetime.d' matched 2 probes ^C iropt 31315 acomp 37037 make.bin 63736 tee 68702 date 84020 sh 91632 dtrace 159200 ctfmerge 321560 install 343300 mcs 394400 get 413695 ctfconvert 594400 bringover 1332465 tail 1335260 # |
La moyenne peut s'avérer utile, mais c'est un élément qui ne fournit pas suffisamment de détails pour comprendre la répartition des points de données. Pour mieux comprendre la répartition, utilisez la fonction de groupement quantize(), comme illustré dans l'exemple suivant :
syscall::write:entry { self->ts = timestamp; } syscall::write:return /self->ts/ { @time[execname] = quantize(timestamp - self->ts); self->ts = 0; }
Étant donné que chaque ligne de sortie devient un diagramme de répartition de fréquences, ce script affiche une sortie nettement plus longue que les précédents : L'exemple suivant présente une sélection de la sortie de test :
lint value ------------- Distribution ------------- count 8192 | 0 16384 | 2 32768 | 0 65536 |@@@@@@@@@@@@@@@@@@@ 74 131072 |@@@@@@@@@@@@@@@ 59 262144 |@@@ 14 524288 | 0 acomp value ------------- Distribution ------------- count 4096 | 0 8192 |@@@@@@@@@@@@ 840 16384 |@@@@@@@@@@@ 750 32768 |@@ 165 65536 |@@@@@@ 460 131072 |@@@@@@ 446 262144 | 16 524288 | 0 1048576 | 1 2097152 | 0 iropt value ------------- Distribution ------------- count 4096 | 0 8192 |@@@@@@@@@@@@@@@@@@@@@@@ 4149 16384 |@@@@@@@@@@ 1798 32768 |@ 332 65536 |@ 325 131072 |@@ 431 262144 | 3 524288 | 2 1048576 | 1 2097152 | 0 |
Vous pouvez remarquer que les lignes de la répartition de fréquences sont toujours des multiples de deux. Chaque ligne indique le compte du nombre d'éléments supérieurs ou égaux à la valeur correspondante mais inférieurs à la valeur supérieure la plus proche. Par exemple, le résultat ci-dessus montre que iropt a 4,149 écritures prenant entre 8,192 nanosecondes et 16,383 nanosecondes incluses.
La fonction quantize() permet d'obtenir un aperçu rapide des données, mais vous souhaitez peut-être observer à la place une répartition linéaire des valeurs. Pour afficher une répartition linéaire des valeurs, utilisez la fonction de groupement lquantize(). La fonction lquantize() prend trois arguments, en plus d'une expression D : une limite inférieure, une limite supérieure et une étape. Par exemple, si vous souhaitez observer la répartition des écritures par descripteur de fichier, une quantification de multiples de deux n'est pas efficace. À la place, utilisez une quantification linéaire avec une plage restreinte, comme illustré dans l'exemple suivant :
syscall::write:entry { @fds[execname] = lquantize(arg0, 0, 100, 1); }
L'exécution de ce script pendant plusieurs secondes permet d'obtenir une grande quantité d'informations. L'exemple suivant montre une sélection de sortie classique :
mountd value ------------- Distribution ------------- count 11 | 0 12 |@ 4 13 | 0 14 |@@@@@@@@@@@@@@@@@@@@@@@@@ 70 15 | 0 16 |@@@@@@@@@@@@ 34 17 | 0 xemacs-20.4 value ------------- Distribution ------------- count 6 | 0 7 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 521 8 | 0 9 | 1 10 | 0 make.bin value ------------- Distribution ------------- count 0 | 0 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3596 2 | 0 3 | 0 4 | 42 5 | 50 6 | 0 acomp value ------------- Distribution ------------- count 0 | 0 1 |@@@@@ 1156 2 | 0 3 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 6635 4 |@ 297 5 | 0 iropt value ------------- Distribution ------------- count 2 | 0 3 | 299 4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20144 5 | 0 |
Vous pouvez également utiliser la fonction de groupement lquantize() pour regrouper le temps écoulé depuis un certain point du passé. Cette technique permet d'observer une modification de comportement au fil du temps. L'exemple suivant affiche la modification dans le comportement de l'appel système sur une durée de vie d'un processus exécutant la commande date(1) :
syscall::exec:return, syscall::exece:return /execname == "date"/ { self->start = vtimestamp; } syscall:::entry /self->start/ { /* * We linearly quantize on the current virtual time minus our * process's start time. We divide by 1000 to yield microseconds * rather than nanoseconds. The range runs from 0 to 10 milliseconds * in steps of 100 microseconds; we expect that no date(1) process * will take longer than 10 milliseconds to complete. */ @a["system calls over time"] = lquantize((vtimestamp - self->start) / 1000, 0, 10000, 100); } syscall::rexit:entry /self->start/ { self->start = 0; }
Le script précédent fournit plus de détails sur le comportement de l'appel système lorsque de nombreux processus date(1) sont exécutés. Pour voir ce résultat, exécutez sh -c 'while true; do date >/dev/null; done' dans une fenêtre, tandis que le script D s'exécute dans une autre. Le script produit un profil du comportement de l'appel système de la commande date(1) :
# dtrace -s dateprof.d dtrace: script './dateprof.d' matched 218 probes ^C system calls over time value ------------- Distribution ------------- count < 0 | 0 0 |@@ 20530 100 |@@@@@@ 48814 200 |@@@ 28119 300 |@ 14646 400 |@@@@@ 41237 500 | 1259 600 | 218 700 | 116 800 |@ 12783 900 |@@@ 28133 1000 | 7897 1100 |@ 14065 1200 |@@@ 27549 1300 |@@@ 25715 1400 |@@@@ 35011 1500 |@@ 16734 1600 | 498 1700 | 256 1800 | 369 1900 | 404 2000 | 320 2100 | 555 2200 | 54 2300 | 17 2400 | 5 2500 | 1 2600 | 7 2700 | 0 |
Ce résultat donne une idée approximative des différentes phases de la commande date(1) par rapport aux services requis du noyau. Pour mieux comprendre ces phases, vous souhaitez peut-être comprendre quels appels système font l'objet d'un appel et à quel moment. Si c'est le cas, vous pouvez modifier le script D pour regrouper la variable probefunc à la place d'une chaîne constante.
Par défaut, plusieurs groupements s'affichent selon leur ordre d'introduction dans le programme D. Vous pouvez ignorer ce comportement en utilisant la fonction printa() pour afficher les groupements. La fonction printa() permet également de formater de façon précise les données de groupement en utilisant une chaîne de format, tel que décrit dans Chapitre12Format de sortie.
Si un groupement n'est pas formaté avec une instruction printa() dans votre programme D, la commande dtrace crée un instantané des données de groupement et affiche les résultats une fois, après l'achèvement du suivi, en utilisant le format de groupement par défaut. Si un groupement donné est formaté avec une instruction printa(), le comportement par défaut est désactivé. Vous pouvez obtenir des résultats équivalents en ajoutant l'instruction printa(@ nom-groupement) à une clause de sonde dtrace:::END dans votre programme. Le format de sortie par défaut des fonctions de groupement avg(), count(), min(), max() et sum() affiche une valeur décimale d'entier correspondant à la valeur groupée de chaque tuple. Le format de sortie par défaut des fonctions de groupement lquantize() et quantize() affiche un tableau ASCII des résultats. Les tuples de groupement sont affichés comme si la fonction trace() était appliquée à chaque élément de tuple.
Lors du groupement de données sur une période donnée, vous souhaitez certainement normaliser les données en fonction d'un facteur constant. Cette technique permet de comparer des données disjointes plus facilement. Par exemple, lors du groupement d'appels système, vous souhaitez certainement afficher comme sortie les appels système en tant que vitesse par seconde au lieu d'une valeur absolue au cours de l'exécution. L'action normalize() de DTrace vous permet ainsi de normaliser des données. Les paramètres sur lesquels doit s'appliquer la fonction normalize() sont un facteur de groupement et de normalisation. La sortie du groupement présente chaque valeur divisée par le facteur de normalisation.
L'exemple suivant présente la méthode de groupement des données par appel système :
#pragma D option quiet BEGIN { /* * Get the start time, in nanoseconds. */ start = timestamp; } syscall:::entry { @func[execname] = count(); } END { /* * Normalize the aggregation based on the number of seconds we have * been running. (There are 1,000,000,000 nanoseconds in one second.) */ normalize(@func, (timestamp - start) / 1000000000); }
L'exécution du script ci-dessus pendant une brève période permet d'obtenir la sortie suivante sur un ordinateur de bureau :
# dtrace -s ./normalize.d ^C syslogd 0 rpc.rusersd 0 utmpd 0 xbiff 0 in.routed 1 sendmail 2 echo 2 FvwmAuto 2 stty 2 cut 2 init 2 pt_chmod 3 picld 3 utmp_update 3 httpd 4 xclock 5 basename 6 tput 6 sh 7 tr 7 arch 9 expr 10 uname 11 mibiisa 15 dirname 18 dtrace 40 ksh 48 java 58 xterm 100 nscd 120 fvwm2 154 prstat 180 perfbar 188 Xsun 1309 .netscape.bin 3005 |
La fonction normalize() définit le facteur de normalisation pour le groupement spécifié, mais cette action ne modifie pas les données sous-jacentes. La fonction denormalize() prend uniquement un groupement. L'ajout de l'action d'annulation de la normalisation à l'exemple précédent renvoie le nombre d'appels système brut ainsi que la vitesse par seconde :
#pragma D option quiet BEGIN { start = timestamp; } syscall:::entry { @func[execname] = count(); } END { this->seconds = (timestamp - start) / 1000000000; printf("Ran for %d seconds.\n", this->seconds); printf("Per-second rate:\n"); normalize(@func, this->seconds); printa(@func); printf("\nRaw counts:\n"); denormalize(@func); printa(@func); }
L'exécution du script ci-dessus pendant une brève période permet d'obtenir une sortie similaire à l'exemple suivant :
# dtrace -s ./denorm.d ^C Ran for 14 seconds. Per-second rate: syslogd 0 in.routed 0 xbiff 1 sendmail 2 elm 2 picld 3 httpd 4 xclock 6 FvwmAuto 7 mibiisa 22 dtrace 42 java 55 xterm 75 adeptedit 118 nscd 127 prstat 179 perfbar 184 fvwm2 296 Xsun 829 Raw counts: syslogd 1 in.routed 4 xbiff 21 sendmail 30 elm 36 picld 43 httpd 56 xclock 91 FvwmAuto 104 mibiisa 314 dtrace 592 java 774 xterm 1062 adeptedit 1665 nscd 1781 prstat 2506 perfbar 2581 fvwm2 4156 Xsun 11616 |
Les groupements peuvent également être renormalisés. Si la fonction normalize() est appelée plusieurs fois pour le même groupement, le facteur de normalisation sera le facteur spécifié dans l'appel le plus récent. L'exemple suivant imprime les vitesses par seconde au fil du temps :
#pragma D option quiet BEGIN { start = timestamp; } syscall:::entry { @func[execname] = count(); } tick-10sec { normalize(@func, (timestamp - start) / 1000000000); printa(@func); }
Lors de l'utilisation de DTrace pour élaborer des scripts de surveillance simples, vous pouvez, de temps en temps, effacer les valeurs d'un groupement en utilisant la fonction clear(). Cette fonction prend comme unique paramètre un groupement. La fonction clear() efface uniquement les valeurs du groupement ; les clés du groupement sont conservées. Par conséquent, la présence d'une clé dans un groupement ayant une valeur associée de zéro indique que la clé avait une valeur différente de zéro qui a été ultérieurement définie sur zéro dans le cadre de l'exécution d'une fonction clear(). Pour rejeter à la fois les valeurs d'un groupement et ses clés, utilisez la fonction trunc(). Pour plus d'informations, reportez-vous à la section Troncature de groupements.
L'exemple suivant ajoute la fonction clear() à l'Exemple 9–1 :
#pragma D option quiet BEGIN { last = timestamp; } syscall:::entry { @func[execname] = count(); } tick-10sec { normalize(@func, (timestamp - last) / 1000000000); printa(@func); clear(@func); last = timestamp; }
Tandis que l'Exemple 9–1 affiche le taux d'appels système sur toute la durée de vie de l'appel dtrace, l'exemple précédent affiche le taux d'appels système uniquement sur les dix dernières secondes.
Lorsque l'on observe des résultats de groupement, ce sont souvent les dix premiers résultats qui présentent un intérêt. Les clés et valeurs associées aux valeurs autres que les valeurs les plus élevées ne présentent pas d'intérêt. Vous souhaitez peut-être également rejeter un résultat de groupement dans son intégralité, en supprimant à la fois les clés et les valeurs. La fonction trunc() de DTrace est utilisée dans ces deux cas de figure.
Les paramètres sur lesquels appliquer la fonction trunc() sont un groupement et une valeur de troncature facultative. Sans la valeur de troncature, trunc() rejette à la fois les valeurs et les clés de groupement du groupement complet. Lorsqu'une valeur de troncature n est présente, trunc() rejette les valeurs et les clés de groupement à l'exception de celles associées aux valeurs n les plus élevées. Cela signifie que trunc(@foo, 10) tronque le groupement appelé foo après les dix premières valeurs, là où trunc(@foo) rejette le groupement dans son intégralité. Le groupement complet est également rejeté si 0 est spécifié comme valeur de troncature.
Pour afficher les valeurs n du bas au lieu de celles du haut, spécifiez une valeur de troncature négative dans trunc(). Par exemple, trunc(@foo, -10) tronque la valeur nommée foo après les dix dernières valeurs.
L'exemple suivant augmente l'exemple d'appel système pour n'afficher que le nombre d'appels système par seconde des dix premières applications d'appels système sur dix secondes :
#pragma D option quiet BEGIN { last = timestamp; } syscall:::entry { @func[execname] = count(); } tick-10sec { trunc(@func, 10); normalize(@func, (timestamp - last) / 1000000000); printa(@func); clear(@func); last = timestamp; }
L'exemple suivant affiche la sortie de l'exécution du script ci-dessus sur un ordinateur portable légèrement chargé :
FvwmAuto 7 telnet 13 ping 14 dtrace 27 xclock 34 MozillaFirebird- 63 xterm 133 fvwm2 146 acroread 168 Xsun 616 telnet 4 FvwmAuto 5 ping 14 dtrace 27 xclock 35 fvwm2 69 xterm 70 acroread 164 MozillaFirebird- 491 Xsun 1287 |
Étant donné que DTrace met en tampon certaines données de groupement dans le noyau, il risque de manquer d'espace disponible lors de l'ajout d'une nouvelle clé au groupement. Dans ce cas, les données sont abandonnées, le compteur incrémenté et dtrace génère un message indiquant l'abandon d'un groupement. Ce cas de figure ne se produit que rarement car DTrace conserve un état d'exécution longue (comprenant la clé du groupement et le résultat intermédiaire) au niveau utilisateur, où l'espace peut être augmenté de façon dynamique. Dans l'éventualité peu probable d'un abandon, vous pouvez augmenter la taille du tampon de groupement avec l'option aggsize pour réduire le risque d'abandons. Vous pouvez également utiliser cette option pour réduire l'empreinte de mémoire de DTrace. Comme c'est la cas avec toutes les options de taille, il est possible de spécifier aggsize avec n'importe quel suffixe de taille. La stratégie de redimensionnement de ce tampon est dictée par l'option bufresize. Pour de plus amples informations sur la mise en tampon, reportez-vous au Chapitre11Tampons et mise en tampon. Pour de plus amples informations sur les détails, reportez-vous au Chapitre16Options et paramètres réglables.
Une autre méthode permettant d'éliminer les abandons de groupement consiste à augmenter la vitesse de consommation des données du groupement au niveau utilisateur. Par défaut, cette vitesse est définie sur une fois par seconde. Elle peut être réglée de façon explicite avec l'option aggrate. Comme avec n'importe quelle option de vitesse, aggrate peut être spécifié avec n'importe quel suffixe temporel mais le suffixe par défaut est le nombre par seconde. Pour de plus amples informations sur l'option aggsize, reportez-vous au Chapitre16Options et paramètres réglables.