1 #!/usr/sbin/dtrace -Zs 2 /* 3 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of Oracle nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 */ 35 36 /* 37 * Usage: 38 * 1. class_loading_stat.d -c "java ..." INTERVAL_SECS 39 * 2. class_loading_stat.d -p JAVA_PID INTERVAL_SECS 40 * 41 * This script collects statistics about loaded and unloaded Java classes 42 * and dump current state to stdout every INTERVAL_SECS seconds. If 43 * INTERVAL_SECS is not set then 10 seconds interval is used. 44 * 45 */ 46 47 #pragma D option quiet 48 #pragma D option destructive 49 #pragma D option defaultargs 50 #pragma D option aggrate=100ms 51 52 53 self char *str_ptr; 54 self string class_name; 55 self string package_name; 56 57 int INTERVAL_SECS; 58 59 :::BEGIN 60 { 61 SAMPLE_NAME = "hotspot class loadin tracing"; 62 63 INTERVAL_SECS = $1 ? $1 : 10; 64 SAMPLING_TIME = timestamp + INTERVAL_SECS * 1000000000ull; 65 66 LOADED_CLASSES_CNT = 0; 67 UNLOADED_CLASSES_CNT = 0; 68 69 LINE_SEP = 70 "------------------------------------------------------------------------"; 71 72 printf("BEGIN %s\n\n", SAMPLE_NAME); 73 } 74 75 /* 76 * hotspot:::class-loaded, hotspot:::class-unloaded probe arguments: 77 * arg0: char*, class name passed as mUTF8 string 78 * arg1: uintptr_t, class name length 79 * arg2: void*, class loader ID, which is unique identifier for 80 * a class loader in the VM. 81 * arg3: uintptr_t, class is shared or not 82 */ 83 hotspot$target:::class-loaded 84 { 85 LOADED_CLASSES_CNT ++; 86 87 self->str_ptr = (char*) copyin(arg0, arg1+1); 88 self->str_ptr[arg1] = '\0'; 89 self->class_name = (string) self->str_ptr; 90 91 self->package_name = dirname(self->class_name); 92 93 @classes_loaded[self->package_name] = count(); 94 } 95 96 hotspot$target:::class-unloaded 97 { 98 UNLOADED_CLASSES_CNT ++; 99 100 self->str_ptr = (char*) copyin(arg0, arg1+1); 101 self->str_ptr[arg1] = '\0'; 102 self->class_name = (string) self->str_ptr; 103 104 self->package_name = dirname(self->class_name); 105 106 @classes_unloaded[self->package_name] = count(); 107 } 108 109 110 tick-1sec 111 /timestamp > SAMPLING_TIME/ 112 { 113 printf("%s\n", LINE_SEP); 114 printf("%Y\n", walltimestamp); 115 printf("%s\n", LINE_SEP); 116 117 printf("Loaded classes by package:\n"); 118 printa("%10@d %s\n", @classes_loaded); 119 120 printf("\n"); 121 printf("Unloaded classes by package:\n"); 122 printa("%10@d %s\n", @classes_unloaded); 123 124 printf("\n"); 125 printf("Number of loaded classes: %10d\n", LOADED_CLASSES_CNT); 126 printf("Number of unloaded classes: %10d\n", UNLOADED_CLASSES_CNT); 127 128 SAMPLING_TIME = timestamp + INTERVAL_SECS * 1000000000ull; 129 } 130 131 132 :::END 133 { 134 printf("%s\n", LINE_SEP); 135 printf("%Y\n", walltimestamp); 136 printf("%s\n", LINE_SEP); 137 138 printf("Loaded classes by package:\n"); 139 printa("%10@d %s\n", @classes_loaded); 140 141 printf("\n"); 142 printf("Unloaded classes by package:\n"); 143 printa("%10@d %s\n", @classes_unloaded); 144 145 printf("\n"); 146 printf("Number of loaded classes: %10d\n", LOADED_CLASSES_CNT); 147 printf("Number of unloaded classes: %10d\n", UNLOADED_CLASSES_CNT); 148 149 printf("\nEND of %s\n", SAMPLE_NAME); 150 } 151 152 syscall::rexit:entry, 153 syscall::exit:entry 154 /pid == $target/ 155 { 156 exit(0); 157 } 158