Skip to content

Commit 56ebb8c

Browse files
JonasNorlinderfiskJonas Norlinder
authored andcommitted
8359110: Log accumulated GC and process CPU time upon VM exit
Co-authored-by: Erik Österlund <eosterlund@openjdk.org> Co-authored-by: Jonas Norlinder <jnorlinder@openjdk.org> Reviewed-by: tschatzl, ayang
1 parent 5cf349c commit 56ebb8c

15 files changed

+245
-14
lines changed

src/hotspot/os/posix/os_posix.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#include <sys/resource.h>
7878
#include <sys/socket.h>
7979
#include <spawn.h>
80+
#include <sys/resource.h>
8081
#include <sys/time.h>
8182
#include <sys/times.h>
8283
#include <sys/types.h>
@@ -1599,6 +1600,17 @@ jlong os::elapsed_frequency() {
15991600
return NANOSECS_PER_SEC; // nanosecond resolution
16001601
}
16011602

1603+
double os::elapsed_process_cpu_time() {
1604+
struct rusage usage;
1605+
int retval = getrusage(RUSAGE_SELF, &usage);
1606+
if (retval == 0) {
1607+
return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec +
1608+
(usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000.0 * 1000.0);
1609+
} else {
1610+
return -1;
1611+
}
1612+
}
1613+
16021614
// Return the real, user, and system times in seconds from an
16031615
// arbitrary fixed point in the past.
16041616
bool os::getTimesSecs(double* process_real_time,

src/hotspot/os/windows/os_windows.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,38 @@ FILETIME java_to_windows_time(jlong l) {
11941194
return result;
11951195
}
11961196

1197+
double os::elapsed_process_cpu_time() {
1198+
FILETIME create;
1199+
FILETIME exit;
1200+
FILETIME kernel;
1201+
FILETIME user;
1202+
1203+
if (GetProcessTimes(GetCurrentProcess(), &create, &exit, &kernel, &user) == 0) {
1204+
return -1;
1205+
}
1206+
1207+
SYSTEMTIME user_total;
1208+
if (FileTimeToSystemTime(&user, &user_total) == 0) {
1209+
return -1;
1210+
}
1211+
1212+
SYSTEMTIME kernel_total;
1213+
if (FileTimeToSystemTime(&kernel, &kernel_total) == 0) {
1214+
return -1;
1215+
}
1216+
1217+
double user_seconds =
1218+
double(user_total.wHour) * 3600.0 + double(user_total.wMinute) * 60.0 +
1219+
double(user_total.wSecond) + double(user_total.wMilliseconds) / 1000.0;
1220+
1221+
double kernel_seconds = double(kernel_total.wHour) * 3600.0 +
1222+
double(kernel_total.wMinute) * 60.0 +
1223+
double(kernel_total.wSecond) +
1224+
double(kernel_total.wMilliseconds) / 1000.0;
1225+
1226+
return user_seconds + kernel_seconds;
1227+
}
1228+
11971229
jlong os::javaTimeMillis() {
11981230
FILETIME wt;
11991231
GetSystemTimeAsFileTime(&wt);

src/hotspot/share/gc/epsilon/epsilonHeap.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class EpsilonHeap : public CollectedHeap {
6767
jint initialize() override;
6868
void initialize_serviceability() override;
6969

70+
void stop() override {};
71+
7072
GrowableArray<GCMemoryManager*> memory_managers() override;
7173
GrowableArray<MemoryPool*> memory_pools() override;
7274

src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ class ParallelScavengeHeap : public CollectedHeap {
155155
void post_initialize() override;
156156
void update_counters();
157157

158+
void stop() override {};
159+
158160
size_t capacity() const override;
159161
size_t used() const override;
160162

src/hotspot/share/gc/serial/serialHeap.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ class SerialHeap : public CollectedHeap {
125125
// Does operations required after initialization has been done.
126126
void post_initialize() override;
127127

128+
void stop() override {};
129+
128130
bool is_in_reserved(const void* addr) const { return _reserved.contains(addr); }
129131

130132
// Performance Counter support

src/hotspot/share/gc/shared/collectedHeap.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "gc/shared/gcWhen.hpp"
3939
#include "gc/shared/memAllocator.hpp"
4040
#include "gc/shared/stringdedup/stringDedup.hpp"
41+
#include "gc/shared/stringdedup/stringDedupProcessor.hpp"
4142
#include "gc/shared/tlab_globals.hpp"
4243
#include "logging/log.hpp"
4344
#include "logging/logStream.hpp"
@@ -200,6 +201,34 @@ void CollectedHeap::print_relative_to_gc(GCWhen::Type when) const {
200201
}
201202
}
202203

204+
class CPUTimeThreadClosure : public ThreadClosure {
205+
private:
206+
jlong _cpu_time = 0;
207+
208+
public:
209+
virtual void do_thread(Thread* thread) {
210+
jlong cpu_time = os::thread_cpu_time(thread);
211+
if (cpu_time != -1) {
212+
_cpu_time += cpu_time;
213+
}
214+
}
215+
jlong cpu_time() { return _cpu_time; };
216+
};
217+
218+
double CollectedHeap::elapsed_gc_cpu_time() const {
219+
double string_dedup_cpu_time = UseStringDeduplication ?
220+
os::thread_cpu_time((Thread*)StringDedup::_processor->_thread) : 0;
221+
222+
if (string_dedup_cpu_time == -1) {
223+
string_dedup_cpu_time = 0;
224+
}
225+
226+
CPUTimeThreadClosure cl;
227+
gc_threads_do(&cl);
228+
229+
return (double)(cl.cpu_time() + _vmthread_cpu_time + string_dedup_cpu_time) / NANOSECS_PER_SEC;
230+
}
231+
203232
void CollectedHeap::print_before_gc() const {
204233
print_relative_to_gc(GCWhen::BeforeGC);
205234
}
@@ -281,6 +310,7 @@ CollectedHeap::CollectedHeap() :
281310
_last_whole_heap_examined_time_ns(os::javaTimeNanos()),
282311
_total_collections(0),
283312
_total_full_collections(0),
313+
_vmthread_cpu_time(0),
284314
_gc_cause(GCCause::_no_gc),
285315
_gc_lastcause(GCCause::_no_gc)
286316
{
@@ -603,6 +633,40 @@ void CollectedHeap::post_initialize() {
603633
initialize_serviceability();
604634
}
605635

636+
void CollectedHeap::log_gc_cpu_time() const {
637+
LogTarget(Info, gc, cpu) out;
638+
if (os::is_thread_cpu_time_supported() && out.is_enabled()) {
639+
double process_cpu_time = os::elapsed_process_cpu_time();
640+
double gc_cpu_time = elapsed_gc_cpu_time();
641+
642+
if (process_cpu_time == -1 || gc_cpu_time == -1) {
643+
log_warning(gc, cpu)("Could not sample CPU time");
644+
return;
645+
}
646+
647+
double usage;
648+
if (gc_cpu_time > process_cpu_time ||
649+
process_cpu_time == 0 || gc_cpu_time == 0) {
650+
// This can happen e.g. for short running processes with
651+
// low CPU utilization
652+
usage = 0;
653+
} else {
654+
usage = 100 * gc_cpu_time / process_cpu_time;
655+
}
656+
out.print("GC CPU usage: %.2f%% (Process: %.4fs GC: %.4fs)", usage, process_cpu_time, gc_cpu_time);
657+
}
658+
}
659+
660+
void CollectedHeap::before_exit() {
661+
print_tracing_info();
662+
663+
// Log GC CPU usage.
664+
log_gc_cpu_time();
665+
666+
// Stop any on-going concurrent work and prepare for exit.
667+
stop();
668+
}
669+
606670
#ifndef PRODUCT
607671

608672
bool CollectedHeap::promotion_should_fail(volatile size_t* count) {

src/hotspot/share/gc/shared/collectedHeap.hpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class CollectedHeap : public CHeapObj<mtGC> {
132132
NOT_PRODUCT(volatile size_t _promotion_failure_alot_count;)
133133
NOT_PRODUCT(volatile size_t _promotion_failure_alot_gc_number;)
134134

135+
jlong _vmthread_cpu_time;
136+
135137
// Reason for current garbage collection. Should be set to
136138
// a value reflecting no collection between collections.
137139
GCCause::Cause _gc_cause;
@@ -206,6 +208,9 @@ class CollectedHeap : public CHeapObj<mtGC> {
206208
return static_cast<T*>(heap);
207209
}
208210

211+
// Stop any onging concurrent work and prepare for exit.
212+
virtual void stop() = 0;
213+
209214
public:
210215

211216
static inline size_t filler_array_max_size() {
@@ -239,13 +244,14 @@ class CollectedHeap : public CHeapObj<mtGC> {
239244
// This is the correct place to place such initialization methods.
240245
virtual void post_initialize();
241246

242-
// Stop any onging concurrent work and prepare for exit.
243-
virtual void stop() {}
247+
void before_exit();
244248

245249
// Stop and resume concurrent GC threads interfering with safepoint operations
246250
virtual void safepoint_synchronize_begin() {}
247251
virtual void safepoint_synchronize_end() {}
248252

253+
void add_vmthread_cpu_time(jlong time);
254+
249255
void initialize_reserved_region(const ReservedHeapSpace& rs);
250256

251257
virtual size_t capacity() const = 0;
@@ -419,6 +425,8 @@ class CollectedHeap : public CHeapObj<mtGC> {
419425

420426
void print_relative_to_gc(GCWhen::Type when) const;
421427

428+
void log_gc_cpu_time() const;
429+
422430
public:
423431
void pre_full_gc_dump(GCTimer* timer);
424432
void post_full_gc_dump(GCTimer* timer);
@@ -455,6 +463,8 @@ class CollectedHeap : public CHeapObj<mtGC> {
455463
// Default implementation does nothing.
456464
virtual void print_tracing_info() const = 0;
457465

466+
double elapsed_gc_cpu_time() const;
467+
458468
void print_before_gc() const;
459469
void print_after_gc() const;
460470

src/hotspot/share/gc/shared/collectedHeap.inline.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,8 @@ inline oop CollectedHeap::class_allocate(Klass* klass, size_t size, TRAPS) {
4646
return allocator.allocate();
4747
}
4848

49+
inline void CollectedHeap::add_vmthread_cpu_time(jlong time) {
50+
_vmthread_cpu_time += time;
51+
}
52+
4953
#endif // SHARE_GC_SHARED_COLLECTEDHEAP_INLINE_HPP

src/hotspot/share/gc/shared/stringdedup/stringDedup.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
#include "oops/oopsHierarchy.hpp"
106106
#include "utilities/globalDefinitions.hpp"
107107

108+
class CollectedHeap;
108109
class Klass;
109110
class StringDedupThread;
110111
class ThreadClosure;
@@ -115,6 +116,7 @@ class ThreadClosure;
115116
// feature. Other functions in the StringDedup class are called where
116117
// needed, without requiring GC-specific code.
117118
class StringDedup : public AllStatic {
119+
friend class CollectedHeap;
118120
friend class StringDedupThread;
119121

120122
class Config;

src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "memory/allocation.hpp"
3030
#include "utilities/macros.hpp"
3131

32+
class CollectedHeap;
3233
class JavaThread;
3334
class OopStorage;
3435

@@ -42,6 +43,8 @@ class OopStorage;
4243
// incremental operations for resizing and for removing dead entries, so
4344
// safepoint checks can be performed between steps in those operations.
4445
class StringDedup::Processor : public CHeapObj<mtGC> {
46+
friend class CollectedHeap;
47+
4548
Processor();
4649
~Processor() = default;
4750

0 commit comments

Comments
 (0)