1 #!/usr/sbin/dtrace -Zs 2 3 /* 4 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * - Neither the name of Oracle nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 */ 36 37 /* 38 * Usage: 39 * 1. object_allocation_stat.d -c "java ..." TOP_RESULTS_COUNT INTERVAL_SECS 40 * 2. object_allocation_stat.d -p JAVA_PID TOP_RESULTS_COUNT INTERVAL_SECS 41 * 42 * This script collects statistics about TOP_RESULTS_COUNT (default is 25) 43 * object allocations every INTERVAL_SECS (default is 60) seconds. 44 * 45 * The results are displayed in ascending order which means that the highest 46 * allocated type is listed last. The script can be improved to sort the 47 * results in reverse order when DTrace supports it. 48 * 49 * Notes: 50 * - The object-alloc probe is disabled by default since it incurs 51 * performance overhead to the application. To trace object-alloc probe, 52 * you need to turn on the ExtendedDTraceProbes VM option. 53 * You can either start the application with -XX:+ExtendedDTraceProbes 54 * option or use the jinfo command to enable it at runtime as follows: 55 * 56 * jinfo -flag +ExtendedDTraceProbes <java_pid> 57 * 58 */ 59 60 #pragma D option quiet 61 #pragma D option destructive 62 #pragma D option defaultargs 63 #pragma D option bufsize=16m 64 #pragma D option aggrate=100ms 65 66 67 self char *str_ptr; 68 self string class_name; 69 70 long long ALLOCATED_OBJECTS_CNT; 71 72 int INTERVAL_SECS; 73 74 :::BEGIN 75 { 76 SAMPLE_NAME = "hotspot object allocation tracing"; 77 78 TOP_RESULTS_COUNT = $1 ? $1 : 25; 79 INTERVAL_SECS = $2 ? $2 : 60; 80 81 ALLOCATED_OBJECTS_CNT = 0; 82 83 SAMPLING_TIME = timestamp + INTERVAL_SECS * 1000000000ull; 84 85 LINE_SEP = 86 "------------------------------------------------------------------------"; 87 88 printf("BEGIN %s\n\n", SAMPLE_NAME); 89 } 90 91 /* 92 * hotspot:::object-alloc probe arguments: 93 * arg0: uintptr_t, Java thread id 94 * arg1: char*, a pointer to mUTF-8 string containing the name of 95 * the class of the object being allocated 96 * arg2: uintptr_t, the length of the class name (in bytes) 97 * arg3: uintptr_t, the size of the object being allocated 98 */ 99 hotspot$target:::object-alloc 100 { 101 ALLOCATED_OBJECTS_CNT ++; 102 103 self->str_ptr = (char*) copyin(arg1, arg2+1); 104 self->str_ptr[arg2] = '\0'; 105 self->class_name = (string) self->str_ptr; 106 107 108 @allocs_count[self->class_name] = count(); 109 @allocs_size[self->class_name] = sum(arg3); 110 } 111 112 tick-1sec 113 /timestamp > SAMPLING_TIME/ 114 { 115 printf("\n"); 116 printf("%s\n", LINE_SEP); 117 printf("%Y\n", walltimestamp); 118 printf("%s\n", LINE_SEP); 119 120 printf("\n"); 121 printf("Top %d allocations by size:\n", TOP_RESULTS_COUNT); 122 trunc(@allocs_size, TOP_RESULTS_COUNT); 123 printa("%10@d %s\n", @allocs_size); 124 125 printf("\n"); 126 printf("Top %d allocations by count:\n", TOP_RESULTS_COUNT); 127 trunc(@allocs_count, TOP_RESULTS_COUNT); 128 printa("%10@d %s\n", @allocs_count); 129 130 printf("\nTotal number of allocated objects: %d\n", ALLOCATED_OBJECTS_CNT); 131 132 SAMPLING_TIME = timestamp + INTERVAL_SECS * 1000000000ull; 133 } 134 135 :::END 136 { 137 printf("\n"); 138 printf("%s\n", LINE_SEP); 139 printf("%Y\n", walltimestamp); 140 printf("%s\n", LINE_SEP); 141 142 printf("\n"); 143 printf("Top %d allocations by size:\n", TOP_RESULTS_COUNT); 144 trunc(@allocs_size, TOP_RESULTS_COUNT); 145 printa("%10@d %s\n", @allocs_size); 146 147 printf("\n"); 148 printf("Top %d allocations by count:\n", TOP_RESULTS_COUNT); 149 trunc(@allocs_count, TOP_RESULTS_COUNT); 150 printa("%10@d %s\n", @allocs_count); 151 152 printf("\nTotal number of allocated objects: %d\n", ALLOCATED_OBJECTS_CNT); 153 154 printf("\nEND of %s\n", SAMPLE_NAME); 155 } 156 157 syscall::rexit:entry, 158 syscall::exit:entry 159 /pid == $target/ 160 { 161 exit(0); 162 } 163