Mercurial > hg > truffle
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. |