231 return JNI_ERR; 232 } 233 live_objects_only = strcmp(arg1, "-live") == 0; 234 } 235 236 // Request a full GC before heap dump if live_objects_only = true 237 // This helps reduces the amount of unreachable objects in the dump 238 // and makes it easier to browse. 239 HeapDumper dumper(live_objects_only /* request GC */); 240 dumper.dump(op->arg(0), out); 241 } 242 return JNI_OK; 243 } 244 245 // Implementation of "inspectheap" command 246 // See also: ClassHistogramDCmd class 247 // 248 // Input arguments :- 249 // arg0: "-live" or "-all" 250 // arg1: Name of the dump file or NULL 251 static jint heap_inspection(AttachOperation* op, outputStream* out) { 252 bool live_objects_only = true; // default is true to retain the behavior before this change is made 253 outputStream* os = out; // if path not specified or path is NULL, use out 254 fileStream* fs = NULL; 255 const char* arg0 = op->arg(0); 256 if (arg0 != NULL && (strlen(arg0) > 0)) { 257 if (strcmp(arg0, "-all") != 0 && strcmp(arg0, "-live") != 0) { 258 out->print_cr("Invalid argument to inspectheap operation: %s", arg0); 259 return JNI_ERR; 260 } 261 live_objects_only = strcmp(arg0, "-live") == 0; 262 } 263 264 const char* path = op->arg(1); 265 if (path != NULL) { 266 if (path[0] == '\0') { 267 out->print_cr("No dump file specified"); 268 } else { 269 // create file 270 fs = new (ResourceObj::C_HEAP, mtInternal) fileStream(path); 271 if (fs == NULL) { 272 out->print_cr("Failed to allocate space for file: %s", path); 273 return JNI_ERR; 274 } 275 os = fs; 276 } 277 } 278 279 VM_GC_HeapInspection heapop(os, live_objects_only /* request full gc */); 280 VMThread::execute(&heapop); 281 if (os != NULL && os != out) { 282 out->print_cr("Heap inspection file created: %s", path); 283 delete fs; 284 } 285 return JNI_OK; 286 } 287 288 // Implementation of "setflag" command 289 static jint set_flag(AttachOperation* op, outputStream* out) { 290 291 const char* name = NULL; 292 if ((name = op->arg(0)) == NULL) { 293 out->print_cr("flag name is missing"); 294 return JNI_ERR; 295 } 296 297 FormatBuffer<80> err_msg("%s", ""); 298 299 int ret = WriteableFlags::set_flag(op->arg(0), op->arg(1), JVMFlag::ATTACH_ON_DEMAND, err_msg); | 231 return JNI_ERR; 232 } 233 live_objects_only = strcmp(arg1, "-live") == 0; 234 } 235 236 // Request a full GC before heap dump if live_objects_only = true 237 // This helps reduces the amount of unreachable objects in the dump 238 // and makes it easier to browse. 239 HeapDumper dumper(live_objects_only /* request GC */); 240 dumper.dump(op->arg(0), out); 241 } 242 return JNI_OK; 243 } 244 245 // Implementation of "inspectheap" command 246 // See also: ClassHistogramDCmd class 247 // 248 // Input arguments :- 249 // arg0: "-live" or "-all" 250 // arg1: Name of the dump file or NULL 251 // arg2: parallel thread number 252 static jint heap_inspection(AttachOperation* op, outputStream* out) { 253 bool live_objects_only = true; // default is true to retain the behavior before this change is made 254 outputStream* os = out; // if path not specified or path is NULL, use out 255 fileStream* fs = NULL; 256 const char* arg0 = op->arg(0); 257 uint parallel_thread_num = MAX(1, (uint)os::initial_active_processor_count() * 3 / 8); 258 if (arg0 != NULL && (strlen(arg0) > 0)) { 259 if (strcmp(arg0, "-all") != 0 && strcmp(arg0, "-live") != 0) { 260 out->print_cr("Invalid argument to inspectheap operation: %s", arg0); 261 return JNI_ERR; 262 } 263 live_objects_only = strcmp(arg0, "-live") == 0; 264 } 265 266 const char* path = op->arg(1); 267 if (path != NULL && path[0] != '\0') { 268 // create file 269 fs = new (ResourceObj::C_HEAP, mtInternal) fileStream(path); 270 if (fs == NULL) { 271 out->print_cr("Failed to allocate space for file: %s", path); 272 } 273 os = fs; 274 } 275 276 const char* num_str = op->arg(2); 277 if (num_str != NULL && num_str[0] != '\0') { 278 uintx num; 279 if (!Arguments::parse_uintx(num_str, &num, 0)) { 280 out->print_cr("Invalid parallel thread number: [%s]", num_str); 281 return JNI_ERR; 282 } 283 parallel_thread_num = num == 0 ? parallel_thread_num : (uint)num; 284 } 285 286 VM_GC_HeapInspection heapop(os, live_objects_only /* request full gc */, parallel_thread_num); 287 VMThread::execute(&heapop); 288 if (os != NULL && os != out) { 289 out->print_cr("Heap inspection file created: %s", path); 290 delete fs; 291 } 292 return JNI_OK; 293 } 294 295 // Implementation of "setflag" command 296 static jint set_flag(AttachOperation* op, outputStream* out) { 297 298 const char* name = NULL; 299 if ((name = op->arg(0)) == NULL) { 300 out->print_cr("flag name is missing"); 301 return JNI_ERR; 302 } 303 304 FormatBuffer<80> err_msg("%s", ""); 305 306 int ret = WriteableFlags::set_flag(op->arg(0), op->arg(1), JVMFlag::ATTACH_ON_DEMAND, err_msg); |