From 0d308e7eb207b8ae5a3955f04e3516683919d59d Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Mon, 16 Sep 2024 00:59:43 +0800 Subject: [PATCH 1/7] Update java-basic-questions-02.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正字符串常量池引用的描述 --- docs/java/basis/java-basic-questions-02.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/java/basis/java-basic-questions-02.md b/docs/java/basis/java-basic-questions-02.md index ed85affa9a2..82449296118 100644 --- a/docs/java/basis/java-basic-questions-02.md +++ b/docs/java/basis/java-basic-questions-02.md @@ -694,12 +694,12 @@ System.out.println(s); **字符串常量池** 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。 ```java -// 在堆中创建字符串对象”ab“ -// 将字符串对象”ab“的引用保存在字符串常量池中 +// 在字符串常量池中创建字符串对象 ”ab“ +// 将字符串对象 ”ab“ 的引用返回给引用 aa String aa = "ab"; -// 直接返回字符串常量池中字符串对象”ab“的引用 +// 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb String bb = "ab"; -System.out.println(aa==bb);// true +System.out.println(aa==bb); // true ``` 更多关于字符串常量池的介绍可以看一下 [Java 内存区域详解](https://javaguide.cn/java/jvm/memory-area.html) 这篇文章。 @@ -708,7 +708,7 @@ System.out.println(aa==bb);// true 会创建 1 或 2 个字符串对象。 -1、如果字符串常量池中不存在字符串对象“abc”的引用,那么它会在堆上创建两个字符串对象,其中一个字符串对象的引用会被保存在字符串常量池中。 +1、如果字符串常量池中不存在字符串对象 “abc”,那么它首先会在字符串常量池中创建字符串对象 "abc",然后在堆内存中再创建其中一个字符串对象 "abc" 示例代码(JDK 1.8): @@ -720,14 +720,14 @@ String s1 = new String("abc"); ![](https://oss.javaguide.cn/github/javaguide/open-source-project/image-20220413175809959.png) -`ldc` 命令用于判断字符串常量池中是否保存了对应的字符串对象的引用,如果保存了的话直接返回,如果没有保存的话,会在堆中创建对应的字符串对象并将该字符串对象的引用保存到字符串常量池中。 +`ldc (load constant)` 指令的作用是从常量池中加载常量,包括字符串常量、整数常量、浮点数常量、或者类引用。这里用于判断字符串常量池中是否保存了对应的字符串对象,如果保存了的话会将它的引用加载到操作数栈,如果没有保存的话,会在字符串常量池中创建对应的字符串对象,并将其引用加载到操作数栈中。 -2、如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”。 +2、如果字符串常量池中已存在字符串对象“abc”,则只会在堆中创建 1 个字符串对象“abc”。 示例代码(JDK 1.8): ```java -// 字符串常量池中已存在字符串对象“abc”的引用 +// 字符串常量池中已存在字符串对象“abc” String s1 = "abc"; // 下面这段代码只会在堆中创建 1 个字符串对象“abc” String s2 = new String("abc"); From d011ff616199f601050ed6c61d8f1ee354f69ddf Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:01:20 +0800 Subject: [PATCH 2/7] Update memory-area.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同步修改字符串常量池的描述 --- docs/java/jvm/memory-area.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/java/jvm/memory-area.md b/docs/java/jvm/memory-area.md index 1d283e9e667..180b1672f39 100644 --- a/docs/java/jvm/memory-area.md +++ b/docs/java/jvm/memory-area.md @@ -242,12 +242,12 @@ Class 文件中除了有类的版本、字段、方法、接口等描述信息 **字符串常量池** 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。 ```java -// 在堆中创建字符串对象”ab“ -// 将字符串对象”ab“的引用保存在字符串常量池中 +// 在字符串常量池中创建字符串对象 ”ab“ +// 将字符串对象 ”ab“ 的引用返回给引用 aa String aa = "ab"; -// 直接返回字符串常量池中字符串对象”ab“的引用 +// 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb String bb = "ab"; -System.out.println(aa==bb);// true +System.out.println(aa==bb); // true ``` HotSpot 虚拟机中字符串常量池的实现是 `src/hotspot/share/classfile/stringTable.cpp` ,`StringTable` 可以简单理解为一个固定大小的`HashTable` ,容量为 `StringTableSize`(可以通过 `-XX:StringTableSize` 参数来设置),保存的是字符串(key)和 字符串对象的引用(value)的映射关系,字符串对象的引用指向堆中的字符串对象。 From 4e431621a51732783096a5084fd9c4a6e3fed5bb Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:03:50 +0800 Subject: [PATCH 3/7] Update java-basic-questions-02.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正描述错误 --- docs/java/basis/java-basic-questions-02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/basis/java-basic-questions-02.md b/docs/java/basis/java-basic-questions-02.md index 82449296118..cf7362a2207 100644 --- a/docs/java/basis/java-basic-questions-02.md +++ b/docs/java/basis/java-basic-questions-02.md @@ -695,7 +695,7 @@ System.out.println(s); ```java // 在字符串常量池中创建字符串对象 ”ab“ -// 将字符串对象 ”ab“ 的引用返回给引用 aa +// 将字符串对象 ”ab“ 的引用赋值给 aa String aa = "ab"; // 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb String bb = "ab"; From afcf129b93b1a99579340989b6af1b87ec4bfa2a Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:04:33 +0800 Subject: [PATCH 4/7] Update memory-area.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正描述 --- docs/java/jvm/memory-area.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/jvm/memory-area.md b/docs/java/jvm/memory-area.md index 180b1672f39..45968d38b45 100644 --- a/docs/java/jvm/memory-area.md +++ b/docs/java/jvm/memory-area.md @@ -243,7 +243,7 @@ Class 文件中除了有类的版本、字段、方法、接口等描述信息 ```java // 在字符串常量池中创建字符串对象 ”ab“ -// 将字符串对象 ”ab“ 的引用返回给引用 aa +// 将字符串对象 ”ab“ 的引用赋值给给 aa String aa = "ab"; // 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb String bb = "ab"; From b5469fc505ec52ceebb93669b41a65bb4c9ea5a8 Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Mon, 16 Sep 2024 22:13:18 +0800 Subject: [PATCH 5/7] Update java-basic-questions-03.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正序列化相关的描述 --- docs/java/basis/java-basic-questions-03.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/basis/java-basic-questions-03.md b/docs/java/basis/java-basic-questions-03.md index 5c71236427a..8d64ab99461 100644 --- a/docs/java/basis/java-basic-questions-03.md +++ b/docs/java/basis/java-basic-questions-03.md @@ -451,8 +451,8 @@ SPI 将服务接口和具体的服务实现分离开来,将服务调用方和 简单来说: -- **序列化**:将数据结构或对象转换成二进制字节流的过程 -- **反序列化**:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程 +- **序列化**:将数据结构或对象转换成可以存储或传输的形式,通常是二进制字节流,也可以是 JSON, XML 等文本格式 +- **反序列化**:将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程 对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。 From b6d1a8cb2e92d32a4a47c6c08d3323f17d614299 Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Mon, 16 Sep 2024 22:13:48 +0800 Subject: [PATCH 6/7] Update serialization.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正序列化相关描述 --- docs/java/basis/serialization.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/java/basis/serialization.md b/docs/java/basis/serialization.md index 3f0dd6f8a74..fb7d3b69e7f 100644 --- a/docs/java/basis/serialization.md +++ b/docs/java/basis/serialization.md @@ -11,8 +11,8 @@ tag: 简单来说: -- **序列化**:将数据结构或对象转换成二进制字节流的过程 -- **反序列化**:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程 +- **序列化**:将数据结构或对象转换成可以存储或传输的形式,通常是二进制字节流,也可以是 JSON, XML 等文本格式 +- **反序列化**:将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程 对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。 From 2c6ed751db7d07ba22244e9cffce6cd03721e363 Mon Sep 17 00:00:00 2001 From: qksuki <105899310+qksuki@users.noreply.github.com> Date: Tue, 17 Sep 2024 20:21:03 +0800 Subject: [PATCH 7/7] Update jvm-garbage-collection.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正GC算法描述问题 --- docs/java/jvm/jvm-garbage-collection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/java/jvm/jvm-garbage-collection.md b/docs/java/jvm/jvm-garbage-collection.md index 885f71ea245..13dd6f09ec6 100644 --- a/docs/java/jvm/jvm-garbage-collection.md +++ b/docs/java/jvm/jvm-garbage-collection.md @@ -353,7 +353,7 @@ JDK1.2 以后,Java 对引用的概念进行了扩充,将引用分为强引 当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将 Java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。 -比如在新生代中,每次收集都会有大量对象死去,所以可以选择“标记-复制”算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。 +比如在新生代中,每次收集都会有大量对象死去,所以可以选择“复制”算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。 **延伸面试问题:** HotSpot 为什么要分为新生代和老年代?