Repository navigation
jcmd monitoredVM
wangkaiwu edited this page May 29, 2022
·
1 revision
static char* mmap_create_shared(size_t size) {
int result;
int fd;
char* mapAddress;
int vmid = os::current_process_id();
char* user_name = get_user_name(geteuid());
char* dirname = get_user_tmp_dir(user_name, vmid, -1);
char* filename = get_sharedmem_filename(dirname, vmid, -1);
char* short_filename = strrchr(filename, '/');
fd = create_sharedmem_resources(dirname, short_filename, size);
// share memory 映射
mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
result = ::close(fd);
return mapAddress;
}static char* create_shared_memory(size_t size) {
return mmap_create_shared(size);
}class PerfMemory : AllStatic {
private:
static char* _start;
static char* _end;
static size_t _capacity;
static PerfDataPrologue* _prologue;
};
void PerfMemory::create_memory_region(size_t size) {
if (PerfDisableSharedMem) {
// 共享内存禁用
} else {
// _start 是分配的 share memory 的起始地址
_start = create_shared_memory(size);
}
if (_start != NULL) _capacity = size;
}
void PerfMemory::initialize() {
size_t capacity = align_up(PerfDataMemorySize,
os::vm_allocation_granularity());
// 申请一块共享内存,容量是 capacity
create_memory_region(capacity);
_prologue = (PerfDataPrologue *)_start;
_end = _start + _capacity;
_top = _start + sizeof(PerfDataPrologue);
// 以下是 perfData 开场白部分的初始化
// 魔数
_prologue->magic = (jint)0xcafec0c0;
// 大小端
_prologue->byte_order = PERFDATA_BIG_ENDIAN;
// perfData 版本
_prologue->major_version = PERFDATA_MAJOR_VERSION;
_prologue->minor_version = PERFDATA_MINOR_VERSION;
_prologue->accessible = 0;
// 数据部分的偏移(刨除了开场白的部分)
_prologue->entry_offset = sizeof(PerfDataPrologue);
// 有多少条数据
_prologue->num_entries = 0;
// 使用了多少
_prologue->used = 0;
// 是否溢出
_prologue->overflow = 0;
// 时间戳
_prologue->mod_time_stamp = 0;
}char* PerfMemory::alloc(size_t size) {
char* result = _top;
_top += size;
_prologue->used = (jint)used();
_prologue->num_entries = _prologue->num_entries + 1;
return result;
}void PerfData::create_entry(BasicType dtype, size_t dsize, size_t vlen) {
size_t dlen = vlen==0 ? 1 : vlen;
size_t size = sizeof(PerfDataEntry) + namelen;
size_t data_start = size;
size += (dsize * dlen);
// psmp 是 alloc 之前的 _top 指针
char* psmp = PerfMemory::alloc(size);
// 可以看出来,entry 的名字是放在 PerfDataEntry 结构体后面的
char* cname = psmp + sizeof(PerfDataEntry);
// 而 valuep 则是数据真正开始的位置(在name后面)
void* valuep = (void*) (psmp + data_start);
// 给 name 赋值
strcpy(cname, name());
// 开始给 PerfDataEntry 赋值,内容大概看看就好
PerfDataEntry* pdep = (PerfDataEntry*)psmp;
pdep->entry_length = (jint)size;
pdep->name_offset = (jint) ((uintptr_t) cname - (uintptr_t) psmp);
pdep->vector_length = (jint)vlen;
pdep->data_type = (jbyte) type2char(dtype);
pdep->data_units = units();
pdep->data_variability = variability();
pdep->flags = (jbyte)flags();
pdep->data_offset = (jint) data_start;
// entry 的起始位置
_pdep = pdep;
// value 的起始位置
_valuep = valuep;
}PerfByteArray::PerfByteArray(CounterNS ns, const char* namep, Units u,
Variability v, jint length)
: PerfData(ns, namep, u, v), _length(length) {
create_entry(T_BYTE, sizeof(jbyte), (size_t)_length);
}class PerfString : public PerfByteArray {
PerfString(CounterNS ns, const char* namep, Variability v, jint length,
const char* initial_value)
: PerfByteArray(ns, namep, U_String, v, length) {
if (is_valid()) set_string(initial_value);
}
};PerfStringConstant::PerfStringConstant(CounterNS ns, const char* namep,
const char* initial_value)
: PerfString(ns, namep, V_Constant,
initial_value == NULL ? 1 :
MIN2((jint)(strlen((char*)initial_value)+1),
(jint)(PerfMaxStringConstLength+1)),
initial_value) {
}class PerfStringVariable : public PerfString {
PerfStringVariable(CounterNS ns, const char* namep, jint max_length,
const char* initial_value)
: PerfString(ns, namep, V_Variable, max_length+1,
initial_value) { }
};PerfLong::PerfLong(CounterNS ns, const char* namep, Units u, Variability v)
: PerfData(ns, namep, u, v) {
create_entry(T_LONG, sizeof(jlong));
}class PerfLongConstant : public PerfLong {
PerfLongConstant(CounterNS ns, const char* namep, Units u,
jlong initial_value=0)
: PerfLong(ns, namep, u, V_Constant) {
if (is_valid()) *(jlong*)_valuep = initial_value;
}
};class PerfLongVariant : public PerfLong {
PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
jlong initial_value=0)
: PerfLong(ns, namep, u, v) {
if (is_valid()) *(jlong*)_valuep = initial_value;
}
};