通过前面的分析,创建的insttanceKlass 都没放入了java_lang_Class::fixup_mirror_list()这里类的数组里面了,所有的instance列举如下
---------------------------------------------list->at(8)
$3 = 0x7f6d6800f2b8 "java/lang/Object"
(gdb) p _klass
$4 = (InstanceKlass *) 0x100000f30
---------------------------------------------list->at(9)
$7 = 0x7f6d68014f58 "java/io/Serializable"
(gdb) p _klass
$8 = (InstanceKlass *) 0x100001120
---------------------------------------------list->at(10)
$9 = 0x7f6d68014fa8 "java/lang/Comparable"
(gdb) p _klass
$10 = (InstanceKlass *) 0x100001308
-----------------------------------------------list->at(11)
(gdb) p name->as_C_string()
$12 = 0x7f6d680156b8 "java/lang/CharSequence"
(gdb) p _klass
$13 = (InstanceKlass *) 0x1000014f0
-----------------------------------------------list->at(12)
(gdb) p name->as_C_string()
$15 = 0x7f6d68014d38 "java/lang/String"
(gdb) p _klass
$16 = (InstanceKlass *) 0x1000016d8
-----------------------------------------------
(gdb) p name->as_C_string()
$17 = 0x7f6d6800ea68 "java/lang/Class"
加载一半就不执行了,不知道为什么
-----------------------------------------------list->at(13)
$8 = 0x7ff06c0100a8 "java/lang/reflect/AnnotatedElement"
(gdb) p _klass
$9 = (InstanceKlass *) 0x100001948
-----------------------------------------------list->at(13)
(gdb) p name->as_C_string()
$11 = 0x7ff06c00ef28 "java/lang/reflect/GenericDeclaration"
(gdb) p _klass
$16 = (InstanceKlass *) 0x100001b30
-------------------------------------------预加载中创建的对象
(gdb) p $26.as_C_string()
$27 = 0x7ff06c009c88 "java/lang/Class"
(gdb) p k
$21 = (InstanceMirrorKlass *) 0x100001f00
--------------------------------------------
最后的java/lang/Class是,不再list中
进入主流程
GrowableArray <Klass*>* list = java_lang_Class::fixup_mirror_list();
int list_length = list->length();
for (int i = 0; i < list_length; i++) {
Klass* k = list->at(i);
assert(k->is_klass(), "List should only hold classes");
EXCEPTION_MARK;
KlassHandle kh(THREAD, k);
java_lang_Class::fixup_mirror(kh, CATCH);
}
说明 上述的list_length为17 , 前面从list->at(8)就是读取的Object,之前的是ArrayKlass类型的对象,现在读取的是k 为 $32 = (TypeArrayKlass *) 0x100000030
-->
java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {create_mirror(k, Handle(NULL), CHECK);}
进入
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
assert(k->java_mirror() == NULL, "should only assign mirror once"); int computed_modifiers = k->compute_modifier_flags(CHECK_0);
k->set_modifier_flags(computed_modifiers);
// Class_klass has to be loaded because it is used to allocate
// the mirror.
if (SystemDictionary::Class_klass_loaded()) {
// Allocate mirror (java.lang.Class instance)
Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0); InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); // It might also have a component mirror. This mirror must already exist.
if (k->oop_is_array()) {
Handle comp_mirror;
if (k->oop_is_typeArray()) {
BasicType type = TypeArrayKlass::cast(k())->element_type();
comp_mirror = Universe::java_mirror(type);
} else {
assert(k->oop_is_objArray(), "Must be");
Klass* element_klass = ObjArrayKlass::cast(k())->element_klass();
assert(element_klass != NULL, "Must have an element klass");
comp_mirror = element_klass->java_mirror();
}
assert(comp_mirror.not_null(), "must have a mirror"); // Two-way link between the array klass and its component mirror:
ArrayKlass::cast(k())->set_component_mirror(comp_mirror());
set_array_klass(comp_mirror(), k());
} else {
assert(k->oop_is_instance(), "Must be"); // Allocate a simple java object for a lock.
// This needs to be a java object because during class initialization
// it can be held across a java call.
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
set_init_lock(mirror(), r); // Set protection domain also
set_protection_domain(mirror(), protection_domain()); // Initialize static fields
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
}
return mirror();
} else {
if (fixup_mirror_list() == NULL) {
GrowableArray<Klass*>* list =
new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true);
set_fixup_mirror_list(list);
}
fixup_mirror_list()->push(k());
return NULL;
}
}
解析橘色标记的橘色就是创建mirror的内存空间,
InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
这个句子的主干是 Klass->allocat_instance(k,xxx),这个Klass就是名字为"java/lang/Class"的instanceKlass对象,这个对象的地址为0x100001f00,这个对象非常重要
那么解析过程如下
//解析宏如下
获取 SystemDictionary::Class_klass() static Klass* name() { return check_klass_##option(_well_known_klasses[Class_klass_knum]); }
--->
static Klass* check_klass_Pre( Klass* k) { return check_klass(k); }
----->
// Fast access to commonly used classes (preloaded)
static Klass* check_klass(Klass* k) {
assert(k != NULL, "preloaded klass not initialized");
return k;
}
(gdb) p k
$21 = (InstanceMirrorKlass *) 0x100001f00
打印对象
(gdb) p *k
$23 = (InstanceMirrorKlass) {
<InstanceKlass> = {
<Klass> = {
<Metadata> = {
<MetaspaceObj> = {<No data fields>},
members of Metadata:
_vptr.Metadata = 0x7ff071f18a50 <vtable for InstanceMirrorKlass+16>,
_valid = 0
},
members of Klass:
_layout_helper = 97,
_super_check_offset = 56,
_name = 0x7ff070064108,
_secondary_super_cache = 0x0,
_secondary_supers = 0x7ff05ada9560,
_primary_supers = {0x100000f30, 0x100001f00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
_java_mirror = 0x0,
_super = 0x100000f30,
_subklass = 0x0,
_next_sibling = 0x100001d18,
_next_link = 0x100001d18,
_class_loader_data = 0x7ff06c02e868,
_modifier_flags = 17,
_access_flags = {
_flags = 538968113
},
_last_biased_lock_bulk_revocation_time = 0,
_prototype_header = 0x1,
_biased_lock_revocation_count = 0,
_modified_oops = 0 '\000',
_accumulated_modified_oops = 0 '\000'
},
members of InstanceKlass:
static _total_instanceKlass_count = 9,
_annotations = 0x0,
_array_klasses = 0x0,
_constants = 0x7ff05ad9da78,
_inner_classes = 0x7ff05ada94f0,
_source_debug_extension = 0x0,
_array_name = 0x0,
_nonstatic_field_size = 20,
_static_field_size = 5,
_generic_signature_index = 796,
_source_file_name_index = 798,
_static_oop_field_count = 3,
_java_fields_count = 20,
_nonstatic_oop_map_size = 1,
_is_marked_dependent = false,
_misc_flags = 34,
_minor_version = 0,
_major_version = 52,
_init_thread = 0x0,
_vtable_len = 5,
_itable_len = 20,
_oop_map_cache = 0x0,
_member_names = 0x0,
_jni_ids = 0x0,
_methods_jmethod_ids = 0x0,
_dependencies = 0x0,
_osr_nmethods_head = 0x0,
_breakpoints = 0x0,
_previous_versions = 0x0,
_cached_class_file = 0x0,
_idnum_allocated_count = 129,
_init_state = 1 '\001',
_reference_type = 0 '\000',
_jvmti_cached_class_field_map = 0x0,
_verify_count = 0,
_methods = 0x7ff05ada19f0,
_default_methods = 0x0,
_local_interfaces = 0x7ff05ada0440,
_transitive_interfaces = 0x7ff05ada9560,
_method_ordering = 0x7ff05ad94048,
_default_vtable_indices = 0x0,
_fields = 0x7ff05ada1898
},
members of InstanceMirrorKlass:
static _offset_of_static_fields = 96
}
(gdb) p k._name
$24 = (Symbol *) 0x7ff070064108 (gdb) p *(Symbol *) 0x7ff070064108
$26 = {
<SymbolBase> = {
<MetaspaceObj> = {<No data fields>},
members of SymbolBase:
_length = 15,
_refcount = -1,
_identity_hash = 813005551
},
members of Symbol:
_body = {106 'j'},
static _total_count = 3
}
(gdb) p $26.as_C_string()
$27 = 0x7ff06c009c88 "java/lang/Class"
以上验证了 0x100001f00 是 java/lang/Class,但是他是预加载了,并没有在.Class文件解析中来创建对象
进入InstanceMirrorKlass::allocate_instance函数
instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
// Query before forming handle.
int size = instance_size(k);
KlassHandle h_k(THREAD, this);
instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL);
return i;
}
进入size()函数
int InstanceMirrorKlass::instance_size(KlassHandle k) {
if (k() != NULL && k->oop_is_instance()) {//不进入
return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
}
return size_helper();
} ---->
int size_helper() const {
return layout_helper_to_size_helper(layout_helper());
}
-------> int layout_helper() const { return _layout_helper; }
那么这个名字为"java/lang/Class"的 _layout_helper
这里看到就是(const InstanceMirrorKlass * const) 0x100001f00 这个对象的成员
打印如下:
members of Klass:
_layout_helper = 97,
还经过了右移处理,返回为12
进入紫色函数
oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS) { HeapWord* obj; obj = common_mem_allocate_init(real_klass, size, CHECK_NULL);
//设置oop的内容
post_allocation_setup_common(klass, obj); oop mirror = (oop)obj;
// 这个是设置oop对象大小属性
java_lang_Class::set_oop_size(mirror, size); // Setup indirections
if (!real_klass.is_null()) {
java_lang_Class::set_klass(mirror, real_klass());
real_klass->set_java_mirror(mirror);
} InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
assert(size == mk->instance_size(real_klass), "should have been set"); // notify jvmti and dtrace
post_allocation_notify(klass, (oop)obj); return mirror;
}
绿色的就是分配函数,进去
HeapWord* CollectedHeap::common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS) {
HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
// 初始化为0的函数
init_obj(obj, size);
return obj;
}
再进去
HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) { // Clear unhandled oops for memory allocation. Memory allocation might
// not take out a lock if from tlab, so clear here.
CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();) if (HAS_PENDING_EXCEPTION) {
NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
return NULL; // caller does a CHECK_0 too
} HeapWord* result = NULL;
if (UseTLAB) {
result = allocate_from_tlab(klass, THREAD, size);
if (result != NULL) {
assert(!HAS_PENDING_EXCEPTION,
"Unexpected exception, will result in uninitialized storage");
return result;
}
}
}
那么UseTLAB=true 就是从TLAB分配内存打印一下
(gdb) p thread->tlab()
$9 = (ThreadLocalAllocBuffer &) @0x7f97cc00b860: {
<CHeapObj<512u>> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f97d4254710 <vtable for ThreadLocalAllocBuffer+16>
}, <No data fields>},
members of ThreadLocalAllocBuffer:
_start = 0xd7580000,
_top = 0xd75803d0,
_pf_top = 0xd7580010,
_end = 0xd75828f0,
_desired_size = 1310,
_refill_waste_limit = 20,
static _target_refills = 50,
_number_of_refills = 1,
_fast_refill_waste = 0,
_slow_refill_waste = 0,
_gc_waste = 0,
_slow_allocations = 0,
_allocation_fraction = {
<CHeapObj<1280u>> = {
<AllocatedObj> = {
_vptr.AllocatedObj = 0x7f97d42429d0 <vtable for AdaptiveWeightedAverage+16>
}, <No data fields>},
members of AdaptiveWeightedAverage:
_average = 0.999450684,
_sample_count = 1,
_weight = 35,
_is_old = false,
static OLD_THRESHOLD = 100,
_last_sample = 0.999450684
},
static _global_stats = 0x7f97cc02d998
}
就是从线程中获取_tlab 然后调用它的allocate函数
inline HeapWord* ThreadLocalAllocBuffer::allocate(size_t size) {
invariants();
HeapWord* obj = top();
if (pointer_delta(end(), obj) >= size) {
// successful thread-local allocation
#ifdef ASSERT
// Skip mangling the space corresponding to the object header to
// ensure that the returned space is not considered parsable by
// any concurrent GC thread.
size_t hdr_size = oopDesc::header_size();
Copy::fill_to_words(obj + hdr_size, size - hdr_size, badHeapWordVal);
#endif // ASSERT
// This addition is safe because we know that top is
// at least size below end, so the add can't wrap.
set_top(obj + size); invariants();
return obj;
}
return NULL;
}
然后 ,看的出来就是将_top = 0xd7580370 + 12 这个是指针加法
加完之后的_top为 0xd75803d0 一共加了0x60,即12*8字节
补充下黄色函数是
void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
assert(obj != NULL, "cannot initialize NULL object");
const size_t hs = oopDesc::header_size();
assert(size >= hs, "unexpected object size");
((oop)obj)->set_klass_gap(0);
Copy::fill_to_aligned_words(obj + hs, size - hs);
} ((oop)obj)->set_klass_gap(0);
--->
inline void oopDesc::set_klass_gap(int v) {
if (UseCompressedClassPointers) {
*(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v;
}
}
//以下返回12 int类型
inline int oopDesc::klass_gap_offset_in_bytes() {
assert(UseCompressedClassPointers, "only applicable to compressed klass pointers");
return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
} Copy::fill_to_aligned_words(obj + hs, size - hs);
--->
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { //count=10
#ifdef AMD64 //在这里执行,一共执行了10次,每次移动8个字节,所以将oop后面的
julong* to = (julong*) tohw; //value 0xd7580380
julong v = ((julong) value << 32) | value;
while (count-- > 0) {
*to++ = v;
}
#else //以下不执行
juint* to = (juint*)tohw;
count *= HeapWordSize / BytesPerInt;
while (count-- > 0) {
*to++ = value;
}
#endif // AMD64
}
最后的执行结果为
执行结果为
(gdb) x/13xg 0xd7580370
0xd7580370: 0xbaadbabebaadbabe 0x00000000baadbabe
0xd7580380: 0x0000000000000000 0x0000000000000000
0xd7580390: 0x0000000000000000 0x0000000000000000
0xd75803a0: 0x0000000000000000 0x0000000000000000
0xd75803b0: 0x0000000000000000 0x0000000000000000
0xd75803c0: 0x0000000000000000 0x0000000000000000
0xd75803d0: 0xbaadbabebaadbabe
红色设置oop内容函数
void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
HeapWord* obj) {
//设置_mark为0x01
post_allocation_setup_no_klass_install(klass, obj);
//设置_metadata._compressed_klass的值为java/lang/Class的压缩指针0x100001f00
post_allocation_install_obj_klass(klass, oop(obj));
}
具体只贴一下代码
void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
HeapWord* objPtr) {
oop obj = (oop)objPtr; assert(obj != NULL, "NULL object pointer");
if (UseBiasedLocking && (klass() != NULL)) {
obj->set_mark(klass->prototype_header());
} else {
// May be bootstrapping
obj->set_mark(markOopDesc::prototype());
}
} 打印java/lang/Class类instanceKlass的属性为
_prototype_header = 0x1,
还有
void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
oop obj) {
// These asserts are kind of complicated because of klassKlass
// and the beginning of the world.
assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
assert(klass() == NULL || klass()->is_klass(), "not a klass");
assert(obj != NULL, "NULL object pointer");
obj->set_klass(klass());
assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
"missing klass");
} inline void oopDesc::set_klass(Klass* k) {
// since klasses are promoted no store check is needed
assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
if (UseCompressedClassPointers) {
*compressed_klass_addr() = Klass::encode_klass_not_null(k);
} else {
*klass_addr() = k;
}
}
//这个压缩指针,就是设置为0x200003e0
inline narrowKlass Klass::encode_klass_not_null(Klass* v) {
assert(!is_null(v), "klass value can never be zero");
assert(check_klass_alignment(v), "Address not aligned");
int shift = Universe::narrow_klass_shift();
uint64_t pd = (uint64_t)(pointer_delta((void*)v, Universe::narrow_klass_base(), 1));
assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
uint64_t result = pd >> shift;
assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
assert(decode_klass(result) == v, "reversibility");
return (narrowKlass)result;
}
进入紫色的函数
void java_lang_Class::set_oop_size(oop java_class, int size) {
assert(_oop_size_offset != 0, "must be set");
java_class->int_field_put(_oop_size_offset, size);
}
先弄清楚了定义java_lang_Class 中的定义
打印的的内容
_klass_offset =64
_array_klass_offset =72
_oop_size_offset =84
_static_oop_field_count_offset =88
_protection_domain_offset = 52
_init_lock_offset =56
_signers_offset=60
offsets_computed=80
一连串后
inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; }
就是那么就是将 _oop_size_offset =84 的位置设置为12
还有灰色函数 是设置mirror 和real_class的对应关系
//设置oop的偏移量为64的时候,为真是instancekass的地址 0x100000030
void java_lang_Class::set_klass(oop java_class, Klass* klass) {
assert(java_lang_Class::is_instance(java_class), "must be a Class object");
java_class->metadata_field_put(_klass_offset, klass);
}
另外的是设置mirror
(gdb) p this
$15 = (TypeArrayKlass * const) 0x100000030
real_klass->set_java_mirror(mirror);
void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); } void Klass::klass_oop_store(oop* p, oop v) {
assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object"); //真是对象的_java_mirror设置为oop
设置klass对象_java_mirror变量值,这个_java_mirror是很重要的呢
以上就结束了 mirror的创建打印一下
(gdb) p mirror
$16 = (oopDesc *) 0xd7580370
(gdb) x/12xg mirror
0xd7580370: 0x0000000000000001 0x00000000200003e0
0xd7580380: 0x0000000000000000 0x0000000000000000
0xd7580390: 0x0000000000000000 0x0000000000000000
0xd75803a0: 0x0000000000000000 0x0000000000000000
0xd75803b0: 0x0000000100000030 0x0000000000000000
0xd75803c0: 0x0000000c00000000 0x0000000000000000
那么就是叶子颜色的函数
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
inline Klass* oopDesc::klass() const {
if (UseCompressedClassPointers) {
return Klass::decode_klass_not_null(_metadata._compressed_klass);
} else {
return _metadata._klass;
}
}
这就是获取了之前设置的压缩指针_klass
(gdb) p mk
$29 = (InstanceMirrorKlass *) 0x100001f00
还有
(gdb) p ** mirror._handle
$28 = {
_mark = 0x1,
_metadata = {
_klass = 0x200003e0,
_compressed_klass = 536871904
},
static _bs = 0x7f6ba401ea48
}
0x200003e0左移3位 得到 0x100001f00
java/lang/Class 内存为 0x100001f00, 处理的对象内存为 0x100000030
进入最*紫色函数
int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
Klass* k = java_lang_Class::as_Klass(obj);
if (k != NULL && k->oop_is_instance()) {
return InstanceKlass::cast(k)->static_oop_field_count();
}
return 0;
} //因为是array返回为0
mirror()函数返回oop对象0xd7580370
还是给oop对象设置内容
void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
assert(_static_oop_field_count_offset != 0, "must be set");
java_class->int_field_put(_static_oop_field_count_offset, size);
}
*灰色
(gdb) p k
$30 = (TypeArrayKlass *) 0x100000030
BasicType type = TypeArrayKlass::cast(k())->element_type();
comp_mirror = Universe::java_mirror(type);
static oop java_mirror(BasicType t) {
assert((uint)t < T_VOID+1, "range check");
return check_mirror(_mirrors[t]);
}
//从上边看的出来type为4 Bool类型 $31 = (oopDesc *) 0xd7580190
(gdb) p _mirrors[4]
$32 = (oopDesc *) 0xd7580190
那么将_mirror[4]设置为comp_mirror
// Two-way link between the array klass and its component mirror:
ArrayKlass::cast(k())->set_component_mirror(comp_mirror());
void set_component_mirror(oop m) { klass_oop_store(&_component_mirror, m); }
// comp_mirror() = 0xd7580190 ,,,k()=0x100000030
//设置oop的72便宜量为0x100000030
set_array_klass(comp_mirror(), k());
void java_lang_Class::set_array_klass(oop java_class, Klass* klass) {
assert(klass->is_klass() && klass->oop_is_array(), "should be array klass");
java_class->metadata_field_put(_array_klass_offset, klass); //off=72
}
最后的oop内存结构为
(gdb) x/12xg 0xd7580370
0xd7580370: 0x0000000000000001 0x00000000200003e0
0xd7580380: 0x0000000000000000 0x0000000000000000
0xd7580390: 0x0000000000000000 0x0000000000000000
0xd75803a0: 0x0000000000000000 0x0000000000000000
0xd75803b0: 0x0000000100000030 0x0000000000000000
0xd75803c0: 0x0000000c00000000 0x0000000000000000
这就结束了mirror的创建arrrayinstancemirror的创建003e
jvm源码解读--07 创建 fixup_mirrors的更多相关文章
-
jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处
之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...
-
jvm源码解读--09 创建oop对象,将static静态变量放置在oop的96 offset处 第二篇
先打断点systemDictionary.cpp 1915行 Universe::fixup_mirrors(CHECK); 进入 void Universe::fixup_mirrors(TRAPS ...
-
JVM 源码解读之 CMS 何时会进行 Full GC
t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...
-
jvm源码解读--17 Java的wait()、notify()学习
write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...
-
jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析
粘贴源码 package com.test; import java.util.Random; public class Test { static int number=12; private in ...
-
jvm源码解读--16 cas 用法解析
CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...
-
jvm源码解读--11 ldc指令的解读
写一个java文件 public static void main(String[] args) { String str1="abc"; String str2 ="a ...
-
jvm源码解读--10 enum WKID 枚举
源码中对于枚举类型WKID的使用 static bool initialize_wk_klass(WKID id, int init_opt, TRAPS); static void initiali ...
-
jvm源码解读--06 Method 方法解析
进入 // Methods bool has_final_method = false; AccessFlags promoted_flags; promoted_flags.set_flags(0) ...
随机推荐
-
tp 中关于大小写的问题
ThinkPHP3.2.3升级的若干问题和注意事项(持续更新) 现把ThinkPHP3.2.2在升级到3.2.3的过程中需要注意和可能的问题整理如下: (无论如何,在升级之前请确认备份) 1.首先3. ...
-
JDBC中的事务-Transaction
事务-Transaction 某些情况下我们希望对数据库的某一操作要么整体成功,要么整体失败,经典的例子就是支付宝提现.例如我们发起了支付宝到银行卡的100元提现申请,我们希望的结果是支付宝余额减少1 ...
-
java之JDBC
java之JDBC 一.什么是JDBC Java 数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提 ...
-
iabtis初探
1.简介 与Hibernate相比,ibatis属于一种半自动的ORM框架,主要解决了java对象与SQL入参及结果集的映射关系.简单易学.容易上手:但是安全性较差,对于金融等对安全要求较高的系统来说 ...
-
Inspinia_admin-V2.3原版(英文)
Inspinia_admin-V2.3原版(英文) Inspinia_admin-V2.3 BootStrap原版(英文) 原版是老外开发的,结果 国内某人翻译成中文版进行二次开发 卖998 演示地址 ...
-
[LeetCode] 120. Triangle _Medium tag: Dynamic Programming
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...
-
嵌入式Linux开发之uboot启动Linux整体流程分析
嵌入式Linux开发之uboot启动Linux整体流程分析 Uboot全称Universal Boot Loader,一个遵循GPL协议的的开源项目,其作用是引导操作系统,支持引导linux.VxWo ...
-
java工具类——java将一串数据按照gzip方式压缩和解压缩
我要整理在工作中用到的工具类分享出来,也方便自己以后查阅使用,这些工具类都是我自己实际工作中使用的 import java.io.ByteArrayInputStream; import java.i ...
-
Prism6下的MEF:基于微软企业库的Cache
通常,应用程序可以将那些频繁访问的数据,以及那些需要大量处理时间来创建的数据存储在内存中,从而提高性能.基于微软的企业库,我们的快速创建一个缓存的实现. 新建PrismSample.Infrastru ...
-
Ubuntu16.04.2 LTS下使用编译安装程序(使用configure、make、 make install)
以安装vim为例. (vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面). 1.获取源文件 首先进入/usr/local下(只是为了方便处理安装文件,位置随意) 用git ...