8277919: OldObjectSample event causing bloat in the class constant pool in JFR recording
Reviewed-by: jbachorik
This commit is contained in:
parent
32139c1a8a
commit
475ec8e6c5
@ -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()) {
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user