mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 18:14:38 +02:00
8014912: Restore PrintSharedSpaces functionality after NPG
Added dumping of object sizes in CDS archive, sorted by MetaspaceObj::Type Reviewed-by: coleenp, acorn
This commit is contained in:
parent
f52e6781ee
commit
9dc36eb923
15 changed files with 301 additions and 36 deletions
|
@ -243,6 +243,147 @@ public:
|
|||
bool reading() const { return false; }
|
||||
};
|
||||
|
||||
// This is for dumping detailed statistics for the allocations
|
||||
// in the shared spaces.
|
||||
class DumpAllocClosure : public Metaspace::AllocRecordClosure {
|
||||
public:
|
||||
|
||||
// Here's poor man's enum inheritance
|
||||
#define SHAREDSPACE_OBJ_TYPES_DO(f) \
|
||||
METASPACE_OBJ_TYPES_DO(f) \
|
||||
f(SymbolHashentry) \
|
||||
f(SymbolBuckets) \
|
||||
f(Other)
|
||||
|
||||
#define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type,
|
||||
#define SHAREDSPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
|
||||
|
||||
enum Type {
|
||||
// Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
|
||||
SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_DECLARE)
|
||||
_number_of_types
|
||||
};
|
||||
|
||||
static const char * type_name(Type type) {
|
||||
switch(type) {
|
||||
SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_NAME_CASE)
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
enum {
|
||||
RO = 0,
|
||||
RW = 1
|
||||
};
|
||||
|
||||
int _counts[2][_number_of_types];
|
||||
int _bytes [2][_number_of_types];
|
||||
int _which;
|
||||
|
||||
DumpAllocClosure() {
|
||||
memset(_counts, 0, sizeof(_counts));
|
||||
memset(_bytes, 0, sizeof(_bytes));
|
||||
};
|
||||
|
||||
void iterate_metaspace(Metaspace* space, int which) {
|
||||
assert(which == RO || which == RW, "sanity");
|
||||
_which = which;
|
||||
space->iterate(this);
|
||||
}
|
||||
|
||||
virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) {
|
||||
assert(int(type) >= 0 && type < MetaspaceObj::_number_of_types, "sanity");
|
||||
_counts[_which][type] ++;
|
||||
_bytes [_which][type] += byte_size;
|
||||
}
|
||||
|
||||
void dump_stats(int ro_all, int rw_all, int md_all, int mc_all);
|
||||
};
|
||||
|
||||
void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all) {
|
||||
rw_all += (md_all + mc_all); // md and mc are all mapped Read/Write
|
||||
int other_bytes = md_all + mc_all;
|
||||
|
||||
// Calculate size of data that was not allocated by Metaspace::allocate()
|
||||
int symbol_count = _counts[RO][MetaspaceObj::SymbolType];
|
||||
int symhash_bytes = symbol_count * sizeof (HashtableEntry<Symbol*, mtSymbol>);
|
||||
int symbuck_count = SymbolTable::the_table()->table_size();
|
||||
int symbuck_bytes = symbuck_count * sizeof(HashtableBucket<mtSymbol>);
|
||||
|
||||
_counts[RW][SymbolHashentryType] = symbol_count;
|
||||
_bytes [RW][SymbolHashentryType] = symhash_bytes;
|
||||
other_bytes -= symhash_bytes;
|
||||
|
||||
_counts[RW][SymbolBucketsType] = symbuck_count;
|
||||
_bytes [RW][SymbolBucketsType] = symbuck_bytes;
|
||||
other_bytes -= symbuck_bytes;
|
||||
|
||||
// TODO: count things like dictionary, vtable, etc
|
||||
_bytes[RW][OtherType] = other_bytes;
|
||||
|
||||
// prevent divide-by-zero
|
||||
if (ro_all < 1) {
|
||||
ro_all = 1;
|
||||
}
|
||||
if (rw_all < 1) {
|
||||
rw_all = 1;
|
||||
}
|
||||
|
||||
int all_ro_count = 0;
|
||||
int all_ro_bytes = 0;
|
||||
int all_rw_count = 0;
|
||||
int all_rw_bytes = 0;
|
||||
|
||||
const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f";
|
||||
const char *sep = "--------------------+---------------------------+---------------------------+--------------------------";
|
||||
const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %";
|
||||
|
||||
tty->print_cr("Detailed metadata info (rw includes md and mc):");
|
||||
tty->print_cr(hdr);
|
||||
tty->print_cr(sep);
|
||||
for (int type = 0; type < int(_number_of_types); type ++) {
|
||||
const char *name = type_name((Type)type);
|
||||
int ro_count = _counts[RO][type];
|
||||
int ro_bytes = _bytes [RO][type];
|
||||
int rw_count = _counts[RW][type];
|
||||
int rw_bytes = _bytes [RW][type];
|
||||
int count = ro_count + rw_count;
|
||||
int bytes = ro_bytes + rw_bytes;
|
||||
|
||||
double ro_perc = 100.0 * double(ro_bytes) / double(ro_all);
|
||||
double rw_perc = 100.0 * double(rw_bytes) / double(rw_all);
|
||||
double perc = 100.0 * double(bytes) / double(ro_all + rw_all);
|
||||
|
||||
tty->print_cr(fmt, name,
|
||||
ro_count, ro_bytes, ro_perc,
|
||||
rw_count, rw_bytes, rw_perc,
|
||||
count, bytes, perc);
|
||||
|
||||
all_ro_count += ro_count;
|
||||
all_ro_bytes += ro_bytes;
|
||||
all_rw_count += rw_count;
|
||||
all_rw_bytes += rw_bytes;
|
||||
}
|
||||
|
||||
int all_count = all_ro_count + all_rw_count;
|
||||
int all_bytes = all_ro_bytes + all_rw_bytes;
|
||||
|
||||
double all_ro_perc = 100.0 * double(all_ro_bytes) / double(ro_all);
|
||||
double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all);
|
||||
double all_perc = 100.0 * double(all_bytes) / double(ro_all + rw_all);
|
||||
|
||||
tty->print_cr(sep);
|
||||
tty->print_cr(fmt, "Total",
|
||||
all_ro_count, all_ro_bytes, all_ro_perc,
|
||||
all_rw_count, all_rw_bytes, all_rw_perc,
|
||||
all_count, all_bytes, all_perc);
|
||||
|
||||
assert(all_ro_bytes == ro_all, "everything should have been counted");
|
||||
assert(all_rw_bytes == rw_all, "everything should have been counted");
|
||||
}
|
||||
|
||||
// Populate the shared space.
|
||||
|
||||
|
@ -454,6 +595,14 @@ void VM_PopulateDumpSharedSpace::doit() {
|
|||
mapinfo->close();
|
||||
|
||||
memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
|
||||
|
||||
if (PrintSharedSpaces) {
|
||||
DumpAllocClosure dac;
|
||||
dac.iterate_metaspace(_loader_data->ro_metaspace(), DumpAllocClosure::RO);
|
||||
dac.iterate_metaspace(_loader_data->rw_metaspace(), DumpAllocClosure::RW);
|
||||
|
||||
dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes));
|
||||
}
|
||||
}
|
||||
|
||||
static void link_shared_classes(Klass* obj, TRAPS) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue