先看bt栈

  1. (gdb) bt
  2. #0 ConstantPool::allocate (loader_data=0x7fe21802e868, length=87, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/oops/constantPool.cpp:47
  3. #1 0x00007fe2206d0bbc in ClassFileParser::parse_constant_pool (this=0x7fe22229a010, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp:331
  4. #2 0x00007fe2206dce84 in ClassFileParser::parseClassFile (this=0x7fe22229a010, name=0x7fe21d4ad0e8, loader_data=0x7fe21802e868, protection_domain=..., host_klass=..., cp_patches=0x0, parsed_name=..., verify=false, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp:3774
  5. #3 0x00007fe2206eb9b5 in ClassFileParser::parseClassFile (this=0x7fe22229a010, name=0x7fe21d4ad0e8, loader_data=0x7fe21802e868, protection_domain=..., parsed_name=..., verify=false, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp:468
  6. #4 0x00007fe2206e97cb in ClassLoader::load_classfile (h_name=0x7fe21d4ad0e8, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/classLoader.cpp:931
  7. #5 0x00007fe220d29903 in SystemDictionary::load_instance_class (class_name=0x7fe21d4ad0e8, class_loader=..., __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1304
  8. #6 0x00007fe220d27ced in SystemDictionary::resolve_instance_class_or_null (name=0x7fe21d4ad0e8, class_loader=..., protection_domain=..., __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:779
  9. #7 0x00007fe220d266be in SystemDictionary::resolve_or_null (class_name=0x7fe21d4ad0e8, class_loader=..., protection_domain=..., __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:232
  10. #8 0x00007fe220d2612f in SystemDictionary::resolve_or_fail (class_name=0x7fe21d4ad0e8, class_loader=..., protection_domain=..., throw_error=true, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:171
  11. #9 0x00007fe220d26451 in SystemDictionary::resolve_or_fail (class_name=0x7fe21d4ad0e8, throw_error=true, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:212
  12. #10 0x00007fe220d2b27b in SystemDictionary::initialize_wk_klass (id=SystemDictionary::Object_klass_knum, init_opt=0, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1866
  13. #11 0x00007fe220d2b39e in SystemDictionary::initialize_wk_klasses_until (limit_id=SystemDictionary::Cloneable_klass_knum, start_id=@0x7fe22229a9ec: SystemDictionary::Object_klass_knum, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1882
  14. #12 0x00007fe220d2eb86 in SystemDictionary::initialize_wk_klasses_through (end_id=SystemDictionary::Class_klass_knum, start_id=@0x7fe22229a9ec: SystemDictionary::Object_klass_knum, __the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp:408
  15. #13 0x00007fe220d2b4d0 in SystemDictionary::initialize_preloaded_classes (__the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1901
  16. #14 0x00007fe220d2b19d in SystemDictionary::initialize (__the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp:1843
  17. #15 0x00007fe220d7c1d1 in Universe::genesis (__the_thread__=0x7fe21800b800) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/memory/universe.cpp:288
  18. #16 0x00007fe220d7e439 in universe2_init () at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/memory/universe.cpp:991
  19. #17 0x00007fe220917a5c in init_globals () at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/runtime/init.cpp:114
  20. #18 0x00007fe220d5f756 in Threads::create_vm (args=0x7fe22229ae40, canTryAgain=0x7fe22229adff) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/runtime/thread.cpp:3424
  21. #19 0x00007fe2209ca232 in JNI_CreateJavaVM (vm=0x7fe22229ae88, penv=0x7fe22229ae80, args=0x7fe22229ae40) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/hotspot/src/share/vm/prims/jni.cpp:5166
  22. #20 0x00007fe221c67780 in InitializeJVM (pvm=0x7fe22229ae88, penv=0x7fe22229ae80, ifn=0x7fe22229ae90) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/jdk/src/share/bin/java.c:1145
  23. #21 0x00007fe221c656f9 in JavaMain (_args=0x7ffe14eb62f0) at /home/atzhang/atzhang/openjdksource/openjdk8/openjdk/jdk/src/share/bin/java.c:371
  24. #22 0x00007fe221e81ea5 in start_thread () from /lib64/libpthread.so.0
  25. #23 0x00007fe22178a9fd in clone () from /lib64/libc.so.6

进入这个函数

  1. ConstantPool*MetaWord(ClassLoaderData* loader_data, int length, TRAPS) {
  2. // Tags are RW but comment below applies to tags also.
  3. Array<u1>* tags = MetadataFactory::new_writeable_array<u1>(loader_data, length, 0, CHECK_NULL);
  4.  
  5. int size = ConstantPool::size(length); //length=87
  6.  
  7. // CDS considerations:
  8. // Allocate read-write but may be able to move to read-only at dumping time
  9. // if all the klasses are resolved. The only other field that is writable is
  10. // the resolved_references array, which is recreated at startup time.
  11. // But that could be moved to InstanceKlass (although a pain to access from
  12. // assembly code). Maybe it could be moved to the cpCache which is RW.
  13. return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
  14. }

上篇写了关于 tags实现的内容

现在解析一下size=的计算,

  1. static int header_size() { return sizeof(ConstantPool)/HeapWordSize; } //计算结果为11
  2. static int size(int length) { return align_object_size(header_size() + length); } //11+87 =98个
  3.  
  4. inline bool is_object_aligned(intptr_t addr) {
  5. return addr == align_object_size(addr);//size=98
  1. }

//在这个sizeof(ConstantPool) 计算出来的为1 不知道为什么,通过分析来得到大小

  1. //查看分配好的常量池
  2. (gdb) p * constant_pool
  3. $13 = (ConstantPool) {
  4. <Metadata> = {<MetaspaceObj> = {<No data fields>},
  5. _vptr.Metadata = 0x7ff4c424c070 <vtable for ConstantPool+16>,
  6. _valid = 0},
  7. _tags = 0x7ff4c01900a8,
  8. _cache = 0x0,
  9. _pool_holder = 0x0,
  10. _operands = 0x0,
  11. _resolved_references = 0x0,
  12. _reference_map = 0x0,
  13. _flags = 0,
  14. _length = 87,
  15. _saved = {_resolved_reference_length = 0, _version = 0},
  16. _lock = 0x7ff4bc06ec38}
  17. (gdb) p sizeof(*constant_pool)
  18. $15 = 88

这个通过对象来查看得到共有11项目,打印内存可以对应上

  1. (gdb) p constant_pool
  2. $1 = (ConstantPool *) 0x7f2563800108
  3. (gdb) x/22x 0x7f2563800108
  4. 0x7f2563800108: 0x86b70070 0x00007f25 0x00000000 0x00000000
  5. 0x7f2563800118: 0x638000a8 0x00007f25 0x00000000 0x00000000
  6. 0x7f2563800128: 0x00000000 0x00000000 0x00000000 0x00000000
  7. 0x7f2563800138: 0x00000000 0x00000000 0x00000000 0x00000000
  8. 0x7f2563800148: 0x00000000 0x00000057 0x00000000 0x00000000
  9. 0x7f2563800158: 0x8006ec38 0x00007f25

需要特别说明的是: ConstantPool类里面有他的父类的,他的父类占用2个8字节空间,一个是虚表,一个是变量

接着

  1. //进入重载new方法
  2. void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
  3. size_t word_size, bool read_only,
  4. MetaspaceObj::Type type, TRAPS) throw() {
  5. // Klass has it's own operator new
  6. return Metaspace::allocate(loader_data, word_size, read_only,
  7. type, CHECK_NULL);
  8. }
  9. //进入元空间进行内存分配
  10. MetaWord* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
  11. bool read_only, MetaspaceObj::Type type, TRAPS) {
  12. if (HAS_PENDING_EXCEPTION) {
  13. assert(false, "Should not allocate with exception pending");
  14. return NULL; // caller does a CHECK_NULL too
  15. }
  16.  
  17. assert(loader_data != NULL, "Should never pass around a NULL loader_data. "
  18. "ClassLoaderData::the_null_class_loader_data() should have been used.");
  19.  
  20. MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
  21.  
  22. // Try to allocate metadata.
  23. MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
  24.  
  25. if (result == NULL) {
  26. // Allocation failed.
  27. if (is_init_completed()) {
  28. // Only start a GC if the bootstrapping has completed.
  29.  
  30. // Try to clean out some memory and retry.
  31. result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
  32. loader_data, word_size, mdtype);
  33. }
  34. }
  35.  
  36. if (result == NULL) {
  37. report_metadata_oome(loader_data, word_size, mdtype, CHECK_NULL);
  38. }
  39.  
  40. // Zero initialize.
  41. Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
  42.  
  43. return result;
  44. }

接着

  1. MetaWord* Metachunk::allocate(size_t word_size) {
  2. MetaWord* result = NULL;
  3. // If available, bump the pointer to allocate.
  4. if (free_word_size() >= word_size) {
  5. result = _top;
  6. _top = _top + word_size;
  7. }
  8. return result;
  9. }

这里面设计一个指针加法,  _top + 8*word_size

可以看出,_top(0x7fd4b8800108) + 98 最终等于 0x7fd4b8800418,是因为指针加法要乘 指针类型大小即8字节

通过汇编验证

  1. (gdb) x/15i $pc
  2. => 0x7fdfce6ef8df <Metachunk::allocate(unsigned long)+63>: mov 0x20(%rax),%rax
  3. 0x7fdfce6ef8e3 <Metachunk::allocate(unsigned long)+67>: mov -0x20(%rbp),%rdx
  4. 0x7fdfce6ef8e7 <Metachunk::allocate(unsigned long)+71>: shl $0x3,%rdx
  5. 0x7fdfce6ef8eb <Metachunk::allocate(unsigned long)+75>: add %rax,%rdx
  6.  
  7. (gdb) p *(long *) ($rax+0x20)
  8. $15 = 140598841622792
  9. (gdb) p/x *(long *)($rax +0x20)
  10. $16 = 0x7fdfb802c108
  11. (gdb) p/x *(long * )($rbp -0x20)
  12. $17 = 0x62

接着

  1. //看一个细节
  2. void MetaspaceAux::inc_used(Metaspace::MetadataType mdtype, size_t words) {
  3. // _allocated_used_words tracks allocations for
  4. // each piece of metadata. Those allocations are
  5. // generally done concurrently by different application
  6. // threads so must be done atomically.
  7. Atomic::add_ptr(words, &_allocated_used_words[mdtype]);
  8. }
  9. 这个
  10. static size_t _allocated_used_words[Metaspace:: MetadataTypeCount];
  11.  
  12. enum MetadataType {
  13. ClassType,
  14. NonClassType,
  15. MetadataTypeCount
  16. };

具体为

  1. (gdb) p mdtype
  2. $9 = Metaspace::NonClassType
  3.  
  4. (gdb) p/x _allocated_used_words[mdtype]
  5. $11 = 0x83
  6. 这里是02
  7. 那么整个过程由 0x21 变为了0x83 差值为0x62 十进制为98,和前面的98相同

这里就完成了constant_pool的创建

jvm源码解读--03 常量池的解析ConstantPool的更多相关文章

  1. jvm源码解读--04 常量池 常量项的解析CONSTANT_Class_info

    接上篇的继续 ConstantPool* constant_pool = ConstantPool::allocate(_loader_data, length, CHECK_(nullHandle) ...

  2. jvm源码解读--05 常量池 常量项的解析JVM_CONSTANT_Utf8

    当index=18的时候JVM_CONSTANT_Utf8 case JVM_CONSTANT_Utf8 : { cfs->guarantee_more(2, CHECK); // utf8_l ...

  3. JVM 源码解读之 CMS 何时会进行 Full GC

    t点击上方"涤生的博客",关注我 转载请注明原创出处,谢谢!如果读完觉得有收获的话,欢迎点赞加关注. 前言 本文内容是基于 JDK 8 在文章 JVM 源码解读之 CMS GC 触 ...

  4. jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处

    之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...

  5. jvm源码解读--17 Java的wait()、notify()学习

    write and debug by 张艳涛 wait()和notify()的通常用法 A线程取得锁,执行wait(),释放锁; B线程取得锁,完成业务后执行notify(),再释放锁; B线程释放锁 ...

  6. java基础进阶一:String源码和String常量池

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...

  7. 从HotSpot VM源码看字符串常量池(StringTable)和intern()方法

    引言 字符串常量池(StringTable)是JVM中一个重要的结构,它有助于避免重复创建相同内容的String对象.那么StringTable是怎么实现的?"把字符串加入到字符串常量池中& ...

  8. jvm源码解读--12 invokspecial指令的解读

    先看代码 package com.zyt.jvmbook; public class Girl extends Person{ public Girl() { int a; } @Override p ...

  9. C# ArrayPool 源码解读之 byte[] 池化

    一:背景 1. 讲故事最近在分析一个 dump 的过程中发现其在 gen2 和 LOH 上有不少size较大的free,仔细看了下,这些free生前大多都是模板引擎生成的html片段的byte[]数组 ...

随机推荐

  1. 学习响应式编程 Reactor (2) - 初识 reactor

    Reactor Reactor 是用于 Java 的异步非阻塞响应式编程框架,同时具备背压控制的能力.它与 Java 8 函数式 Api 直接集成,比如 分为CompletableFuture.Str ...

  2. 空指针的解决方案Optional包装类

    有道云笔记地址 (建议有道云打开,markdown文档,直接拷贝过来有一些问题) 引言 在java的开发中,有一个问题始终会伴随着开发的进程.记得我第一个项目的时候,有一个同事在评论我的代码的时候说到 ...

  3. c 语言学习第一天

    编辑器:Dev-C++ 变量命名(标识符) 变量名只能是英文字母[A-Z,a-z]和数字[0-9]或者下划线[_]组成. 第一个字母必须是字母或者下划线开头. 变量名区分大小写.例如:Fish≠fis ...

  4. 『无为则无心』Python基础 — 12、Python运算符详细介绍

    目录 1.表达式介绍 2.运算符 (1)运算符的分类 (2)算数运算符 (3)赋值运算符 (4)复合赋值运算符 (5)比较运算符 3.逻辑运算符 拓展1:数字之间的逻辑运算 拓展2:Python中逻辑 ...

  5. 7.6、openstack网络拓扑

    1.openstack官方架构图: 2.openstack服务常用服务的端口号: mysql:3306 keystone:5000 memcache:11211 rabbitmq:5672 rabbi ...

  6. ACdream 1007 a+b 快速幂 java秒啊,快速幂 避免 负数移位出错

    a + b ( sigma  (ai^x)  )  %  mod 1 import java.util.*; 2 import java.math.*; 3 import java.io.*; 4 p ...

  7. Java Set HashSet

    import java.util.HashSet; import java.util.Set; /** Set存储特点:数据无序.不可重复 Set接口的实现类: HashSet:Set接口的主要实现类 ...

  8. AcWing 1252. 搭配购买

    #include<bits/stdc++.h> #define N 10010 using namespace std; int fa[N],v[N],pr[N]; int vv[N],p ...

  9. docker下创建redis cluster集群

    概述 在Redis中,集群的解决方案有三种 主从复制 哨兵机制 Cluster Redis Cluster是Redis的分布式解决方案,在 3.0 版本正式推出. 准备工作 1.确定本机IP地址 2. ...

  10. 解决spring boot中文乱码问题

    在开发或学习当中,我们不可避免的会碰到中文乱码的问题(好想哭,但还是要保持微笑!) 今天,在学习spring boot中碰到了中文乱码问题. 首先,看了一下workspace是不是设置utf-8默认字 ...