jvm 05JVM - 对象的创建 ,oop模型,字符串常量池

01.JVM - 对象的创建

1、对象的创建的方式
在这里插入图片描述
Java语言中,对象创建的方式有六种:

  • new关键字:最常见的形式、Xxx的静态方法、XxxBuilder、XxxFactory的静态方法。

  • Class类的newInstance()方法:通过反射的方式创建对象,调用类的无参构造器进行对象的创建,且其访问权限为public。

  • Constructor的newInstance()方法:通过反射的方式创建对象,调用类的无参、有参构造器进行对象的创建,对构造器访问权限没有要求。

  • 使用clone()方法:不调用任何构造器,但是要求当前类实现Cloneable接口,重写clone()方法。

  • 使用序列化:从文件、网络中获取一个对象的二进制流。

  • 使用第三方库:Objenesis。

02.oop模型

2.1oop模型

在这里插入图片描述
1、非数组对象 InstaceOopDesc

2、数组对象 arrayOopDesc

    2.1 基本数据类型数组 typeArrayOopDesc

    2.2 引用类型数组 objArrayOopDesc

3、MarkOopDesc

    存放锁信息、分代年龄等

2.2 oop和Klass关系

1、InstanceKlass是JVM中表示类的对象的数据结构。JVM在加载class时,会创建instanceKlass,表示其元数据,包括常量池,字段,方法等,存放在方法区,instanceKlass是JVM中的数据结构;
2、 InstanceOopDesc是JVM中表示实例对象的数据结构。在new一个对象时,JVM创建instanceOopDesc来表示这个对象,存放在堆中,其引用存放在栈中;instanceOopDesc对应Java中的对象实例;
3、new操作返回的instanceOopDesc类型指针指向instanceKlass,而instanceKlass指向对应类型的Class实例的instanceOopDesc;
4、在JDK6中,Class对象存放在方法区,JDK7和JDK8中,Class对象存放在Java堆中。

03.字符串常量池

即String Pool,但是JVM中对应的类是StringTable,底层实现是一个hashtable,看代码

class StringTable : public Hashtable<oop, mtSymbol> {
……

Key的生成方式

1、通过String的内容+长度生成hash值
2、将hash值转为key

hashValue = hash_string(name, len);
index = hash_to_index(hashValue);
// Pick hashing algorithm
unsigned int StringTable::hash_string(const jchar* s, int len) {
  return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
                                    java_lang_String::hash_code(s, len);
}
  // Bucket handling
  int hash_to_index(unsigned int full_hash) {
    int h = full_hash % _table_size;
    assert(h >= 0 && h < _table_size, "Illegal hash value");
    return h;
  }

Value的生成方式

将Java的String类的实例instanceOopDesc封装成HashtableEntry

String的两种创建方式:

第一种方式是在常量池中获取字符串对象。
第二种方式是直接在堆空间创建一个新的字符串对象。
//先检查字符串常量池中有没有“apesource”,如果字符产常量池中没有,则创建一个,然后str1指向字符串床常量池中的对象,如果有,则直接将str1指向“apesource”
String str1 = "apesource";
String str2 = new String("apesource");//堆中创建一个新的对象
String str3 = new String("apesource");//堆中创建一个新的对象

System.out.println(str1 == str2);//false
System.out.println(str2 == str3);//false

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述
字符串拼接:
01.
在这里插入图片描述
02.
在这里插入图片描述
03.

public class TestString_5 {

    public static void main(String[] args) {

    }

    public static void test2() {
        String s1 = "1";
        String s2 = "1";

        String s = s1 + s2;
    }
}

在这里插入图片描述
用到了StringBuilder
return new String(this.value, 0, this.count);
不会去查常量池的

双引号 + new String

public class TestString_6 {

    public static void main(String[] args) {

    }

    public static void test2() {
        String s1 = "1";
        String s2 = new String("1");

        String s = s1 + s2;
    }
}

在这里插入图片描述

相关推荐

  1. jvm字符串常量问题

    2024-07-09 19:18:09       24 阅读
  2. JVM常量

    2024-07-09 19:18:09       40 阅读
  3. 理解JVM常量

    2024-07-09 19:18:09       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 19:18:09       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 19:18:09       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 19:18:09       57 阅读
  4. Python语言-面向对象

    2024-07-09 19:18:09       68 阅读

热门阅读

  1. 使用Zookeeper实现分布式锁的最佳实践

    2024-07-09 19:18:09       25 阅读
  2. 每天一个数据分析题(四百十一)- 主成分

    2024-07-09 19:18:09       29 阅读
  3. python教程---网络爬虫

    2024-07-09 19:18:09       27 阅读
  4. Emacs 的优点及与 DE 的比较

    2024-07-09 19:18:09       23 阅读
  5. react VS vue

    2024-07-09 19:18:09       23 阅读
  6. Qt使用笔记1(智能指针,deleteLater,多屏)

    2024-07-09 19:18:09       29 阅读
  7. Vue Router:History 模式 vs. Hash 模式

    2024-07-09 19:18:09       24 阅读
  8. 等保测评新趋势:应对数字化转型中的安全挑战

    2024-07-09 19:18:09       30 阅读
  9. ZCC8801Low Noise High PSRR 1 Ch 500mA/1.0A Alternative LDO

    2024-07-09 19:18:09       29 阅读
  10. Kubernetes(k8s)和Docker Compose本质区别

    2024-07-09 19:18:09       30 阅读
  11. docker-compose部署node-exporter

    2024-07-09 19:18:09       24 阅读
  12. 美国大带宽服务器租用优势和注意事项

    2024-07-09 19:18:09       26 阅读