8329488: Move OopStorage code from safepoint cleanup and remove safepoint cleanup code
Reviewed-by: kbarrett, eosterlund
This commit is contained in:
parent
77a217df60
commit
3e9c381166
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -410,7 +410,7 @@ OopStorage::Block::block_for_ptr(const OopStorage* owner, const oop* ptr) {
|
||||
// allocations until some entries in it are released.
|
||||
//
|
||||
// release() is performed lock-free. (Note: This means it can't notify the
|
||||
// service thread of pending cleanup work. It must be lock-free because
|
||||
// ServiceThread of pending cleanup work. It must be lock-free because
|
||||
// it is called in all kinds of contexts where even quite low ranked locks
|
||||
// may be held.) release() first looks up the block for
|
||||
// the entry, using address alignment to find the enclosing block (thereby
|
||||
@ -705,7 +705,7 @@ void OopStorage::Block::release_entries(uintx releasing, OopStorage* owner) {
|
||||
// Only request cleanup for to-empty transitions, not for from-full.
|
||||
// There isn't any rush to process from-full transitions. Allocation
|
||||
// will reduce deferrals before allocating new blocks, so may process
|
||||
// some. And the service thread will drain the entire deferred list
|
||||
// some. And the ServiceThread will drain the entire deferred list
|
||||
// if there are any pending to-empty transitions.
|
||||
if (releasing == old_allocated) {
|
||||
owner->record_needs_cleanup();
|
||||
@ -880,67 +880,51 @@ bool OopStorage::should_report_num_dead() const {
|
||||
}
|
||||
|
||||
// Managing service thread notifications.
|
||||
//
|
||||
// We don't want cleanup work to linger indefinitely, but we also don't want
|
||||
// to run the service thread too often. We're also very limited in what we
|
||||
// can do in a release operation, where cleanup work is created.
|
||||
//
|
||||
|
||||
// When a release operation changes a block's state to empty, it records the
|
||||
// need for cleanup in both the associated storage object and in the global
|
||||
// request state. A safepoint cleanup task notifies the service thread when
|
||||
// request state. The ServiceThread checks at timed intervals if
|
||||
// there may be cleanup work for any storage object, based on the global
|
||||
// request state. But that notification is deferred if the service thread
|
||||
// has run recently, and we also avoid duplicate notifications. The service
|
||||
// thread updates the timestamp and resets the state flags on every iteration.
|
||||
// request state. We don't want to run empty block cleanup too often in the
|
||||
// face of frequent explicit ServiceThread wakeups, hence the defer period.
|
||||
|
||||
// Global cleanup request state.
|
||||
static volatile bool needs_cleanup_requested = false;
|
||||
|
||||
// Flag for avoiding duplicate notifications.
|
||||
static bool needs_cleanup_triggered = false;
|
||||
// Time after which a cleanup is permitted.
|
||||
static jlong cleanup_permit_time = 0;
|
||||
|
||||
// Time after which a notification can be made.
|
||||
static jlong cleanup_trigger_permit_time = 0;
|
||||
|
||||
// Minimum time since last service thread check before notification is
|
||||
// permitted. The value of 500ms was an arbitrary choice; frequent, but not
|
||||
// too frequent.
|
||||
const jlong cleanup_trigger_defer_period = 500 * NANOSECS_PER_MILLISEC;
|
||||
|
||||
void OopStorage::trigger_cleanup_if_needed() {
|
||||
MonitorLocker ml(Service_lock, Monitor::_no_safepoint_check_flag);
|
||||
if (Atomic::load(&needs_cleanup_requested) &&
|
||||
!needs_cleanup_triggered &&
|
||||
(os::javaTimeNanos() > cleanup_trigger_permit_time)) {
|
||||
needs_cleanup_triggered = true;
|
||||
ml.notify_all();
|
||||
}
|
||||
}
|
||||
// Minimum time between ServiceThread cleanups.
|
||||
// The value of 500ms was an arbitrary choice; frequent, but not too frequent.
|
||||
const jlong cleanup_defer_period = 500 * NANOSECS_PER_MILLISEC;
|
||||
|
||||
bool OopStorage::has_cleanup_work_and_reset() {
|
||||
assert_lock_strong(Service_lock);
|
||||
cleanup_trigger_permit_time =
|
||||
os::javaTimeNanos() + cleanup_trigger_defer_period;
|
||||
needs_cleanup_triggered = false;
|
||||
// Set the request flag false and return its old value.
|
||||
// Needs to be atomic to avoid dropping a concurrent request.
|
||||
// Can't use Atomic::xchg, which may not support bool.
|
||||
return Atomic::cmpxchg(&needs_cleanup_requested, true, false);
|
||||
|
||||
if (Atomic::load_acquire(&needs_cleanup_requested) &&
|
||||
os::javaTimeNanos() > cleanup_permit_time) {
|
||||
cleanup_permit_time =
|
||||
os::javaTimeNanos() + cleanup_defer_period;
|
||||
// Set the request flag false and return its old value.
|
||||
Atomic::release_store(&needs_cleanup_requested, false);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Record that cleanup is needed, without notifying the Service thread.
|
||||
// Used by release(), where we can't lock even Service_lock.
|
||||
// Record that cleanup is needed, without notifying the Service thread, because
|
||||
// we can't lock the Service_lock. Used by release().
|
||||
void OopStorage::record_needs_cleanup() {
|
||||
// Set local flag first, else service thread could wake up and miss
|
||||
// the request. This order may instead (rarely) unnecessarily notify.
|
||||
// Set local flag first, else ServiceThread could wake up and miss
|
||||
// the request.
|
||||
Atomic::release_store(&_needs_cleanup, true);
|
||||
Atomic::release_store_fence(&needs_cleanup_requested, true);
|
||||
}
|
||||
|
||||
bool OopStorage::delete_empty_blocks() {
|
||||
// Service thread might have oopstorage work, but not for this object.
|
||||
// Check for deferred updates even though that's not a service thread
|
||||
// trigger; since we're here, we might as well process them.
|
||||
// ServiceThread might have oopstorage work, but not for this object.
|
||||
// But check for deferred updates, which might provide cleanup work.
|
||||
if (!Atomic::load_acquire(&_needs_cleanup) &&
|
||||
(Atomic::load_acquire(&_deferred_updates) == nullptr)) {
|
||||
return false;
|
||||
@ -986,7 +970,7 @@ bool OopStorage::delete_empty_blocks() {
|
||||
// Don't interfere with an active concurrent iteration.
|
||||
// Instead, give up immediately. There is more work to do,
|
||||
// but don't re-notify, to avoid useless spinning of the
|
||||
// service thread. Instead, iteration completion notifies.
|
||||
// ServiceThread. Instead, iteration completion notifies.
|
||||
if (_concurrent_iteration_count > 0) return true;
|
||||
_active_array->remove(block);
|
||||
}
|
||||
@ -998,10 +982,8 @@ bool OopStorage::delete_empty_blocks() {
|
||||
ThreadBlockInVM tbiv(JavaThread::current());
|
||||
}
|
||||
}
|
||||
// Exceeded work limit or can't delete last block. This will
|
||||
// cause the service thread to loop, giving other subtasks an
|
||||
// opportunity to run too. There's no need for a notification,
|
||||
// because we are part of the service thread (unless gtesting).
|
||||
// Exceeded work limit or can't delete last block so still needs cleanup
|
||||
// for the next time.
|
||||
record_needs_cleanup();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
This code is free software; you can redistribute it and/or modify it
|
||||
@ -684,17 +684,6 @@
|
||||
<Field type="int" name="iterations" label="Iterations" description="Number of state check iterations" />
|
||||
</Event>
|
||||
|
||||
<Event name="SafepointCleanup" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup" description="Safepointing begin running cleanup tasks"
|
||||
thread="true">
|
||||
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
|
||||
</Event>
|
||||
|
||||
<Event name="SafepointCleanupTask" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint Cleanup Task" description="Safepointing begin running cleanup tasks"
|
||||
thread="true">
|
||||
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
|
||||
<Field type="string" name="name" label="Task Name" description="The task name" />
|
||||
</Event>
|
||||
|
||||
<Event name="SafepointEnd" category="Java Virtual Machine, Runtime, Safepoint" label="Safepoint End" description="Safepointing end" thread="true">
|
||||
<Field type="ulong" name="safepointId" label="Safepoint Identifier" relation="SafepointId" />
|
||||
</Event>
|
||||
|
@ -1282,6 +1282,11 @@ const int ObjectAlignmentInBytes = 8;
|
||||
"(0 means none)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(intx, ServiceThreadCleanupInterval, 1000, DIAGNOSTIC, \
|
||||
"Wake the ServiceThread to do periodic cleanup checks every so " \
|
||||
"many milliseconds (0 means none)") \
|
||||
range(0, max_jint) \
|
||||
\
|
||||
product(double, SafepointTimeoutDelay, 10000, \
|
||||
"Delay in milliseconds for option SafepointTimeout; " \
|
||||
"supports sub-millisecond resolution with fractional values.") \
|
||||
|
@ -80,12 +80,6 @@ static void post_safepoint_begin_event(EventSafepointBegin& event,
|
||||
}
|
||||
}
|
||||
|
||||
static void post_safepoint_cleanup_event(EventSafepointCleanup& event, uint64_t safepoint_id) {
|
||||
if (event.should_commit()) {
|
||||
event.set_safepointId(safepoint_id);
|
||||
event.commit();
|
||||
}
|
||||
}
|
||||
|
||||
static void post_safepoint_synchronize_event(EventSafepointStateSynchronization& event,
|
||||
uint64_t safepoint_id,
|
||||
@ -101,16 +95,6 @@ static void post_safepoint_synchronize_event(EventSafepointStateSynchronization&
|
||||
}
|
||||
}
|
||||
|
||||
static void post_safepoint_cleanup_task_event(EventSafepointCleanupTask& event,
|
||||
uint64_t safepoint_id,
|
||||
const char* name) {
|
||||
if (event.should_commit()) {
|
||||
event.set_safepointId(safepoint_id);
|
||||
event.set_name(name);
|
||||
event.commit();
|
||||
}
|
||||
}
|
||||
|
||||
static void post_safepoint_end_event(EventSafepointEnd& event, uint64_t safepoint_id) {
|
||||
if (event.should_commit()) {
|
||||
event.set_safepointId(safepoint_id);
|
||||
@ -435,14 +419,7 @@ void SafepointSynchronize::begin() {
|
||||
|
||||
SafepointTracing::synchronized(nof_threads, initial_running, _nof_threads_hit_polling_page);
|
||||
|
||||
// We do the safepoint cleanup first since a GC related safepoint
|
||||
// needs cleanup to be completed before running the GC op.
|
||||
EventSafepointCleanup cleanup_event;
|
||||
do_cleanup_tasks();
|
||||
post_safepoint_cleanup_event(cleanup_event, _safepoint_id);
|
||||
|
||||
post_safepoint_begin_event(begin_event, _safepoint_id, nof_threads, _current_jni_active_count);
|
||||
SafepointTracing::cleanup();
|
||||
}
|
||||
|
||||
void SafepointSynchronize::disarm_safepoint() {
|
||||
@ -507,68 +484,6 @@ void SafepointSynchronize::end() {
|
||||
post_safepoint_end_event(event, safepoint_id());
|
||||
}
|
||||
|
||||
class ParallelCleanupTask : public WorkerTask {
|
||||
private:
|
||||
SubTasksDone _subtasks;
|
||||
|
||||
class Tracer {
|
||||
private:
|
||||
const char* _name;
|
||||
EventSafepointCleanupTask _event;
|
||||
TraceTime _timer;
|
||||
|
||||
public:
|
||||
Tracer(const char* name) :
|
||||
_name(name),
|
||||
_event(),
|
||||
_timer(name, TRACETIME_LOG(Info, safepoint, cleanup)) {}
|
||||
~Tracer() {
|
||||
post_safepoint_cleanup_task_event(_event, SafepointSynchronize::safepoint_id(), _name);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
ParallelCleanupTask() :
|
||||
WorkerTask("Parallel Safepoint Cleanup"),
|
||||
_subtasks(SafepointSynchronize::SAFEPOINT_CLEANUP_NUM_TASKS) {}
|
||||
|
||||
uint expected_num_workers() const {
|
||||
uint workers = 0;
|
||||
|
||||
return MAX2<uint>(1, workers);
|
||||
}
|
||||
|
||||
void work(uint worker_id) {
|
||||
if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP)) {
|
||||
// Don't bother reporting event or time for this very short operation.
|
||||
// To have any utility we'd also want to report whether needed.
|
||||
OopStorage::trigger_cleanup_if_needed();
|
||||
}
|
||||
|
||||
_subtasks.all_tasks_claimed();
|
||||
}
|
||||
};
|
||||
|
||||
// Various cleaning tasks that should be done periodically at safepoints.
|
||||
void SafepointSynchronize::do_cleanup_tasks() {
|
||||
|
||||
TraceTime timer("safepoint cleanup tasks", TRACETIME_LOG(Info, safepoint, cleanup));
|
||||
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
assert(heap != nullptr, "heap not initialized yet?");
|
||||
ParallelCleanupTask cleanup;
|
||||
WorkerThreads* cleanup_workers = heap->safepoint_workers();
|
||||
const uint expected_num_workers = cleanup.expected_num_workers();
|
||||
if (cleanup_workers != nullptr && expected_num_workers > 1) {
|
||||
// Parallel cleanup using GC provided thread pool.
|
||||
const uint num_workers = MIN2(expected_num_workers, cleanup_workers->active_workers());
|
||||
cleanup_workers->run_task(&cleanup, num_workers);
|
||||
} else {
|
||||
// Serial cleanup using VMThread.
|
||||
cleanup.work(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Methods for determining if a JavaThread is safepoint safe.
|
||||
|
||||
// False means unsafe with undetermined state.
|
||||
@ -946,7 +861,6 @@ void ThreadSafepointState::handle_polling_page_exception() {
|
||||
|
||||
jlong SafepointTracing::_last_safepoint_begin_time_ns = 0;
|
||||
jlong SafepointTracing::_last_safepoint_sync_time_ns = 0;
|
||||
jlong SafepointTracing::_last_safepoint_cleanup_time_ns = 0;
|
||||
jlong SafepointTracing::_last_safepoint_end_time_ns = 0;
|
||||
jlong SafepointTracing::_last_app_time_ns = 0;
|
||||
int SafepointTracing::_nof_threads = 0;
|
||||
@ -954,7 +868,6 @@ int SafepointTracing::_nof_running = 0;
|
||||
int SafepointTracing::_page_trap = 0;
|
||||
VM_Operation::VMOp_Type SafepointTracing::_current_type;
|
||||
jlong SafepointTracing::_max_sync_time = 0;
|
||||
jlong SafepointTracing::_max_cleanup_time = 0;
|
||||
jlong SafepointTracing::_max_vmop_time = 0;
|
||||
uint64_t SafepointTracing::_op_count[VM_Operation::VMOp_Terminating] = {0};
|
||||
|
||||
@ -970,7 +883,7 @@ static void print_header(outputStream* st) {
|
||||
|
||||
st->print("VM Operation "
|
||||
"[ threads: total initial_running ]"
|
||||
"[ time: sync cleanup vmop total ]");
|
||||
"[ time: sync vmop total ]");
|
||||
|
||||
st->print_cr(" page_trap_count");
|
||||
}
|
||||
@ -999,11 +912,9 @@ void SafepointTracing::statistics_log() {
|
||||
_nof_threads,
|
||||
_nof_running);
|
||||
ls.print("[ "
|
||||
INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " "
|
||||
INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " ]",
|
||||
INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " " INT64_FORMAT_W(10) " ]",
|
||||
(int64_t)(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns),
|
||||
(int64_t)(_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns),
|
||||
(int64_t)(_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns),
|
||||
(int64_t)(_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns),
|
||||
(int64_t)(_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns));
|
||||
|
||||
ls.print_cr(INT32_FORMAT_W(16), _page_trap);
|
||||
@ -1024,8 +935,6 @@ void SafepointTracing::statistics_exit_log() {
|
||||
|
||||
log_info(safepoint, stats)("Maximum sync time " INT64_FORMAT" ns",
|
||||
(int64_t)(_max_sync_time));
|
||||
log_info(safepoint, stats)("Maximum cleanup time " INT64_FORMAT" ns",
|
||||
(int64_t)(_max_cleanup_time));
|
||||
log_info(safepoint, stats)("Maximum vm operation time (except for Exit VM operation) "
|
||||
INT64_FORMAT " ns",
|
||||
(int64_t)(_max_vmop_time));
|
||||
@ -1038,7 +947,6 @@ void SafepointTracing::begin(VM_Operation::VMOp_Type type) {
|
||||
// update the time stamp to begin recording safepoint time
|
||||
_last_safepoint_begin_time_ns = os::javaTimeNanos();
|
||||
_last_safepoint_sync_time_ns = 0;
|
||||
_last_safepoint_cleanup_time_ns = 0;
|
||||
|
||||
_last_app_time_ns = _last_safepoint_begin_time_ns - _last_safepoint_end_time_ns;
|
||||
_last_safepoint_end_time_ns = 0;
|
||||
@ -1054,19 +962,12 @@ void SafepointTracing::synchronized(int nof_threads, int nof_running, int traps)
|
||||
RuntimeService::record_safepoint_synchronized(_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns);
|
||||
}
|
||||
|
||||
void SafepointTracing::cleanup() {
|
||||
_last_safepoint_cleanup_time_ns = os::javaTimeNanos();
|
||||
}
|
||||
|
||||
void SafepointTracing::end() {
|
||||
_last_safepoint_end_time_ns = os::javaTimeNanos();
|
||||
|
||||
if (_max_sync_time < (_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns)) {
|
||||
_max_sync_time = _last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns;
|
||||
}
|
||||
if (_max_cleanup_time < (_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns)) {
|
||||
_max_cleanup_time = _last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns;
|
||||
}
|
||||
if (_max_vmop_time < (_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns)) {
|
||||
_max_vmop_time = _last_safepoint_end_time_ns - _last_safepoint_sync_time_ns;
|
||||
}
|
||||
@ -1078,14 +979,12 @@ void SafepointTracing::end() {
|
||||
"Safepoint \"%s\", "
|
||||
"Time since last: " JLONG_FORMAT " ns, "
|
||||
"Reaching safepoint: " JLONG_FORMAT " ns, "
|
||||
"Cleanup: " JLONG_FORMAT " ns, "
|
||||
"At safepoint: " JLONG_FORMAT " ns, "
|
||||
"Total: " JLONG_FORMAT " ns",
|
||||
VM_Operation::name(_current_type),
|
||||
_last_app_time_ns,
|
||||
_last_safepoint_sync_time_ns - _last_safepoint_begin_time_ns,
|
||||
_last_safepoint_cleanup_time_ns - _last_safepoint_sync_time_ns,
|
||||
_last_safepoint_end_time_ns - _last_safepoint_cleanup_time_ns,
|
||||
_last_safepoint_end_time_ns - _last_safepoint_sync_time_ns,
|
||||
_last_safepoint_end_time_ns - _last_safepoint_begin_time_ns
|
||||
);
|
||||
|
||||
|
@ -68,13 +68,6 @@ class SafepointSynchronize : AllStatic {
|
||||
// VM thread and any NonJavaThread may be running.
|
||||
};
|
||||
|
||||
// The enums are listed in the order of the tasks when done serially.
|
||||
enum SafepointCleanupTasks {
|
||||
SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP,
|
||||
// Leave this one last.
|
||||
SAFEPOINT_CLEANUP_NUM_TASKS
|
||||
};
|
||||
|
||||
private:
|
||||
friend class SafepointMechanism;
|
||||
friend class ThreadSafepointState;
|
||||
@ -155,8 +148,6 @@ public:
|
||||
// Exception handling for page polling
|
||||
static void handle_polling_page_exception(JavaThread *thread);
|
||||
|
||||
static void do_cleanup_tasks();
|
||||
|
||||
static void set_is_at_safepoint() { _state = _synchronized; }
|
||||
static void set_is_not_at_safepoint() { _state = _not_synchronized; }
|
||||
|
||||
@ -239,7 +230,6 @@ private:
|
||||
// Absolute
|
||||
static jlong _last_safepoint_begin_time_ns;
|
||||
static jlong _last_safepoint_sync_time_ns;
|
||||
static jlong _last_safepoint_cleanup_time_ns;
|
||||
static jlong _last_safepoint_end_time_ns;
|
||||
|
||||
// Relative
|
||||
@ -251,7 +241,6 @@ private:
|
||||
|
||||
static VM_Operation::VMOp_Type _current_type;
|
||||
static jlong _max_sync_time;
|
||||
static jlong _max_cleanup_time;
|
||||
static jlong _max_vmop_time;
|
||||
static uint64_t _op_count[VM_Operation::VMOp_Terminating];
|
||||
|
||||
@ -262,7 +251,6 @@ public:
|
||||
|
||||
static void begin(VM_Operation::VMOp_Type type);
|
||||
static void synchronized(int nof_threads, int nof_running, int traps);
|
||||
static void cleanup();
|
||||
static void end();
|
||||
|
||||
static void statistics_exit_log();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -126,8 +126,9 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
|
||||
(cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) |
|
||||
(jvmti_tagmap_work = JvmtiTagMap::has_object_free_events_and_reset())
|
||||
) == 0) {
|
||||
// Wait until notified that there is some work to do.
|
||||
ml.wait();
|
||||
// Wait until notified that there is some work to do or timer expires.
|
||||
// Some cleanup requests don't notify the ServiceThread so work needs to be done at periodic intervals.
|
||||
ml.wait(ServiceThreadCleanupInterval);
|
||||
}
|
||||
|
||||
if (has_jvmti_events) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
;
|
||||
; Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
; Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
;
|
||||
; This code is free software; you can redistribute it and/or modify it
|
||||
@ -525,13 +525,13 @@ form = "COLUMN 'Event Count', 'First Recorded Event', 'Last Recorded Event',
|
||||
[jvm.safepoints]
|
||||
label = "Safepoints"
|
||||
table = "COLUMN 'Start Time', 'Duration',
|
||||
'State Syncronization', 'Cleanup',
|
||||
'State Syncronization',
|
||||
'JNI Critical Threads', 'Total Threads'
|
||||
SELECT B.startTime, DIFF([B|E].startTime),
|
||||
S.duration, C.duration,
|
||||
S.duration,
|
||||
jniCriticalThreadCount, totalThreadCount
|
||||
FROM SafepointBegin AS B, SafepointEnd AS E,
|
||||
SafepointCleanup AS C, SafepointStateSynchronization AS S
|
||||
SafepointStateSynchronization AS S
|
||||
GROUP BY safepointId ORDER BY B.startTime"
|
||||
|
||||
[jvm.longest-compilations]
|
||||
|
@ -200,16 +200,6 @@
|
||||
<setting name="threshold">10 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SafepointCleanup">
|
||||
<setting name="enabled">false</setting>
|
||||
<setting name="threshold">10 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SafepointCleanupTask">
|
||||
<setting name="enabled">false</setting>
|
||||
<setting name="threshold">10 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SafepointEnd">
|
||||
<setting name="enabled">false</setting>
|
||||
<setting name="threshold">10 ms</setting>
|
||||
|
@ -200,16 +200,6 @@
|
||||
<setting name="threshold">0 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SafepointCleanup">
|
||||
<setting name="enabled">false</setting>
|
||||
<setting name="threshold">0 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SafepointCleanupTask">
|
||||
<setting name="enabled">false</setting>
|
||||
<setting name="threshold">0 ms</setting>
|
||||
</event>
|
||||
|
||||
<event name="jdk.SafepointEnd">
|
||||
<setting name="enabled">false</setting>
|
||||
<setting name="threshold">0 ms</setting>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -55,7 +55,7 @@ public class TestReclaimStringsLeaksMemory {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ArrayList<String> baseargs = new ArrayList<>(Arrays.asList("-Xms256M",
|
||||
"-Xmx256M",
|
||||
"-Xlog:gc*,stringtable*=debug:gc.log",
|
||||
"-Xlog:gc*,stringtable*=debug,oopstorage+blocks=debug:gc.log",
|
||||
"-XX:NativeMemoryTracking=summary",
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:+PrintNMTStatistics" ));
|
||||
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149991
|
||||
* @summary safepoint+cleanup=info should have output from the code
|
||||
* @requires vm.flagless
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @run driver SafepointCleanupTest
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
public class SafepointCleanupTest {
|
||||
static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("[safepoint,cleanup]");
|
||||
output.shouldContain("safepoint cleanup tasks");
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldNotContain("[safepoint,cleanup]");
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:safepoint+cleanup=info",
|
||||
InnerClass.class.getName());
|
||||
analyzeOutputOn(pb);
|
||||
|
||||
pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:safepoint+cleanup=off",
|
||||
InnerClass.class.getName());
|
||||
analyzeOutputOff(pb);
|
||||
}
|
||||
|
||||
public static class InnerClass {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Safepoint Cleanup test");
|
||||
}
|
||||
}
|
||||
}
|
@ -56,8 +56,7 @@ public class TestLookForUntestedEvents {
|
||||
Arrays.asList(
|
||||
"DataLoss", "IntFlag", "ReservedStackActivation", "NativeLibraryUnload",
|
||||
"DoubleFlag", "UnsignedLongFlagChanged", "IntFlagChanged",
|
||||
"UnsignedIntFlag", "UnsignedIntFlagChanged", "DoubleFlagChanged",
|
||||
"SafepointCleanupTask")
|
||||
"UnsignedIntFlag", "UnsignedIntFlagChanged", "DoubleFlagChanged")
|
||||
);
|
||||
|
||||
// GC uses specific framework to test the events, instead of using event names literally.
|
||||
|
@ -52,7 +52,6 @@ public class TestSafepointEvents {
|
||||
static final String[] EVENT_NAMES = new String[] {
|
||||
EventNames.SafepointBegin,
|
||||
EventNames.SafepointStateSynchronization,
|
||||
EventNames.SafepointCleanup,
|
||||
EventNames.SafepointEnd
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -65,8 +65,6 @@ public class EventNames {
|
||||
public static final String ClassUnload = PREFIX + "ClassUnload";
|
||||
public static final String SafepointBegin = PREFIX + "SafepointBegin";
|
||||
public static final String SafepointStateSynchronization = PREFIX + "SafepointStateSynchronization";
|
||||
public static final String SafepointCleanup = PREFIX + "SafepointCleanup";
|
||||
public static final String SafepointCleanupTask = PREFIX + "SafepointCleanupTask";
|
||||
public static final String SafepointEnd = PREFIX + "SafepointEnd";
|
||||
public static final String ExecuteVMOperation = PREFIX + "ExecuteVMOperation";
|
||||
public static final String Shutdown = PREFIX + "Shutdown";
|
||||
|
Loading…
Reference in New Issue
Block a user