comparison src/share/vm/utilities/ostream.cpp @ 3767:2a241e764894

6941923: RFE: Handling large log files produced by long running Java Applications Summary: supply optinal flags to realize gc log rotation Reviewed-by: ysr, jwilhelm
author minqi
date Fri, 10 Jun 2011 15:08:36 -0700
parents 8010c8c623ac
children f08d439fab8c
comparison
equal deleted inserted replaced
3765:ae5b2f1dcf12 3767:2a241e764894
347 } 347 }
348 348
349 fileStream::~fileStream() { 349 fileStream::~fileStream() {
350 if (_file != NULL) { 350 if (_file != NULL) {
351 if (_need_close) fclose(_file); 351 if (_need_close) fclose(_file);
352 _file = NULL; 352 _file = NULL;
353 } 353 }
354 } 354 }
355 355
356 void fileStream::flush() { 356 void fileStream::flush() {
357 fflush(_file); 357 fflush(_file);
373 if (_fd != -1) { 373 if (_fd != -1) {
374 // Make an unused local variable to avoid warning from gcc 4.x compiler. 374 // Make an unused local variable to avoid warning from gcc 4.x compiler.
375 size_t count = ::write(_fd, s, (int)len); 375 size_t count = ::write(_fd, s, (int)len);
376 } 376 }
377 update_position(s, len); 377 update_position(s, len);
378 }
379
380 rotatingFileStream::~rotatingFileStream() {
381 if (_file != NULL) {
382 if (_need_close) fclose(_file);
383 _file = NULL;
384 FREE_C_HEAP_ARRAY(char, _file_name);
385 _file_name = NULL;
386 }
387 }
388
389 rotatingFileStream::rotatingFileStream(const char* file_name) {
390 _cur_file_num = 0;
391 _bytes_writen = 0L;
392 _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10);
393 jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
394 _file = fopen(_file_name, "w");
395 _need_close = true;
396 }
397
398 rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
399 _cur_file_num = 0;
400 _bytes_writen = 0L;
401 _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10);
402 jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
403 _file = fopen(_file_name, opentype);
404 _need_close = true;
405 }
406
407 void rotatingFileStream::write(const char* s, size_t len) {
408 if (_file != NULL) {
409 // Make an unused local variable to avoid warning from gcc 4.x compiler.
410 size_t count = fwrite(s, 1, len, _file);
411 Atomic::add((jlong)count, &_bytes_writen);
412 }
413 update_position(s, len);
414 }
415
416 // rotate_log must be called from VMThread at safepoint. In case need change parameters
417 // for gc log rotation from thread other than VMThread, a sub type of VM_Operation
418 // should be created and be submitted to VMThread's operation queue. DO NOT call this
419 // function directly. Currently, it is safe to rotate log at safepoint through VMThread.
420 // That is, no mutator threads and concurrent GC threads run parallel with VMThread to
421 // write to gc log file at safepoint. If in future, changes made for mutator threads or
422 // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
423 // must be synchronized.
424 void rotatingFileStream::rotate_log() {
425 if (_bytes_writen < (jlong)GCLogFileSize) return;
426 #ifdef ASSERT
427 Thread *thread = Thread::current();
428 assert(thread == NULL ||
429 (thread->is_VM_thread() && SafepointSynchronize::is_at_safepoint()),
430 "Must be VMThread at safepoint");
431 #endif
432 if (NumberOfGCLogFiles == 1) {
433 // rotate in same file
434 rewind();
435 _bytes_writen = 0L;
436 return;
437 }
438
439 // rotate file in names file.0, file.1, file.2, ..., file.<MaxGCLogFileNumbers-1>
440 // close current file, rotate to next file
441 if (_file != NULL) {
442 _cur_file_num ++;
443 if (_cur_file_num >= NumberOfGCLogFiles) _cur_file_num = 0;
444 jio_snprintf(_file_name, strlen(Arguments::gc_log_filename()) + 10, "%s.%d",
445 Arguments::gc_log_filename(), _cur_file_num);
446 fclose(_file);
447 _file = NULL;
448 }
449 _file = fopen(_file_name, "w");
450 if (_file != NULL) {
451 _bytes_writen = 0L;
452 _need_close = true;
453 } else {
454 tty->print_cr("failed to open rotation log file %s due to %s\n",
455 _file_name, strerror(errno));
456 _need_close = false;
457 }
378 } 458 }
379 459
380 defaultStream* defaultStream::instance = NULL; 460 defaultStream* defaultStream::instance = NULL;
381 int defaultStream::_output_fd = 1; 461 int defaultStream::_output_fd = 1;
382 int defaultStream::_error_fd = 2; 462 int defaultStream::_error_fd = 2;
747 // For -Xloggc:<file> option - called in runtime/thread.cpp 827 // For -Xloggc:<file> option - called in runtime/thread.cpp
748 // Note : this must be called AFTER ostream_init() 828 // Note : this must be called AFTER ostream_init()
749 829
750 gclog_or_tty = tty; // default to tty 830 gclog_or_tty = tty; // default to tty
751 if (Arguments::gc_log_filename() != NULL) { 831 if (Arguments::gc_log_filename() != NULL) {
752 fileStream * gclog = new(ResourceObj::C_HEAP) 832 fileStream * gclog = UseGCLogFileRotation ?
753 fileStream(Arguments::gc_log_filename()); 833 new(ResourceObj::C_HEAP)
834 rotatingFileStream(Arguments::gc_log_filename()) :
835 new(ResourceObj::C_HEAP)
836 fileStream(Arguments::gc_log_filename());
754 if (gclog->is_open()) { 837 if (gclog->is_open()) {
755 // now we update the time stamp of the GC log to be synced up 838 // now we update the time stamp of the GC log to be synced up
756 // with tty. 839 // with tty.
757 gclog->time_stamp().update_to(tty->time_stamp().ticks()); 840 gclog->time_stamp().update_to(tty->time_stamp().ticks());
758 gclog_or_tty = gclog; 841 }
759 } 842 gclog_or_tty = gclog;
760 } 843 }
761 844
762 // If we haven't lazily initialized the logfile yet, do it now, 845 // If we haven't lazily initialized the logfile yet, do it now,
763 // to avoid the possibility of lazy initialization during a VM 846 // to avoid the possibility of lazy initialization during a VM
764 // crash, which can affect the stability of the fatal error handler. 847 // crash, which can affect the stability of the fatal error handler.