8277919: OldObjectSample event causing bloat in the class constant pool in JFR recording

Reviewed-by: jbachorik
This commit is contained in:
Markus Grönlund 2021-12-14 13:00:39 +00:00
parent 32139c1a8a
commit 475ec8e6c5
3 changed files with 12 additions and 9 deletions

View File

@ -202,7 +202,7 @@ static void prepare_for_resolution() {
static bool stack_trace_precondition(const ObjectSample* sample) { static bool stack_trace_precondition(const ObjectSample* sample) {
assert(sample != NULL, "invariant"); assert(sample != NULL, "invariant");
return sample->has_stack_trace_id() && !sample->is_dead(); return sample->has_stack_trace_id() && !sample->is_dead() && !sample->stacktrace().valid();
} }
class StackTraceBlobInstaller { class StackTraceBlobInstaller {
@ -249,7 +249,7 @@ void StackTraceBlobInstaller::install(ObjectSample* sample) {
writer.write_type(TYPE_STACKTRACE); writer.write_type(TYPE_STACKTRACE);
writer.write_count(1); writer.write_count(1);
ObjectSampleCheckpoint::write_stacktrace(stack_trace, writer); ObjectSampleCheckpoint::write_stacktrace(stack_trace, writer);
blob = writer.copy(); blob = writer.move();
_cache.put(sample, blob); _cache.put(sample, blob);
sample->set_stacktrace(blob); sample->set_stacktrace(blob);
} }
@ -278,7 +278,7 @@ void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler) {
} }
static bool is_klass_unloaded(traceid klass_id) { static bool is_klass_unloaded(traceid klass_id) {
assert(ClassLoaderDataGraph_lock->owned_by_self(), "invariant"); assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
return JfrKlassUnloading::is_unloaded(klass_id); return JfrKlassUnloading::is_unloaded(klass_id);
} }
@ -381,6 +381,12 @@ void ObjectSampleCheckpoint::write(const ObjectSampler* sampler, EdgeStore* edge
assert(sampler != NULL, "invariant"); assert(sampler != NULL, "invariant");
assert(edge_store != NULL, "invariant"); assert(edge_store != NULL, "invariant");
assert(thread != NULL, "invariant"); assert(thread != NULL, "invariant");
{
// First install stacktrace blobs for the most recently added candidates.
MutexLocker lock(SafepointSynchronize::is_at_safepoint() ? nullptr : ClassLoaderDataGraph_lock);
// the lock is needed to ensure the unload lists do not grow in the middle of inspection.
install_stack_traces(sampler);
}
write_sample_blobs(sampler, emit_all, thread); write_sample_blobs(sampler, emit_all, thread);
// write reference chains // write reference chains
if (!edge_store->is_empty()) { if (!edge_store->is_empty()) {

View File

@ -232,6 +232,7 @@ int write__klass(JfrCheckpointWriter* writer, const void* k) {
int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) { int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) {
assert(k != NULL, "invariant"); assert(k != NULL, "invariant");
KlassPtr klass = (KlassPtr)k; KlassPtr klass = (KlassPtr)k;
CLEAR_LEAKP(klass);
return write_klass(writer, klass, true); return write_klass(writer, klass, true);
} }
@ -835,7 +836,7 @@ class MethodIteratorHost {
private: private:
MethodCallback _method_cb; MethodCallback _method_cb;
KlassCallback _klass_cb; KlassCallback _klass_cb;
MethodUsedPredicate<leakp> _method_used_predicate; MethodUsedPredicate _method_used_predicate;
MethodFlagPredicate<leakp> _method_flag_predicate; MethodFlagPredicate<leakp> _method_flag_predicate;
public: public:
MethodIteratorHost(JfrCheckpointWriter* writer, MethodIteratorHost(JfrCheckpointWriter* writer,

View File

@ -146,16 +146,12 @@ class SymbolPredicate {
} }
}; };
template <bool leakp>
class MethodUsedPredicate { class MethodUsedPredicate {
bool _current_epoch; bool _current_epoch;
public: public:
MethodUsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {} MethodUsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {}
bool operator()(const Klass* klass) { bool operator()(const Klass* klass) {
if (_current_epoch) { return _current_epoch ? METHOD_USED_THIS_EPOCH(klass) : METHOD_USED_PREVIOUS_EPOCH(klass);
return leakp ? IS_LEAKP(klass) : METHOD_USED_THIS_EPOCH(klass);
}
return leakp ? IS_LEAKP(klass) : METHOD_USED_PREVIOUS_EPOCH(klass);
} }
}; };