Skip to content

Commit 74fc413

Browse files
authored
Merge pull request #2484 from qksuki/main
修正一些关于字符串常量池,序列化,GC 算法的描述
2 parents d243984 + 2c6ed75 commit 74fc413

5 files changed

+17
-17
lines changed

docs/java/basis/java-basic-questions-02.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -694,12 +694,12 @@ System.out.println(s);
694694
**字符串常量池**JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
695695
696696
```java
697-
// 在堆中创建字符串对象”ab“
698-
// 将字符串对象”ab“的引用保存在字符串常量池中
697+
// 在字符串常量池中创建字符串对象 ”ab“
698+
// 将字符串对象 ”ab“ 的引用赋值给 aa
699699
String aa = "ab";
700-
// 直接返回字符串常量池中字符串对象”ab“的引用
700+
// 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb
701701
String bb = "ab";
702-
System.out.println(aa==bb);// true
702+
System.out.println(aa==bb); // true
703703
```
704704
705705
更多关于字符串常量池的介绍可以看一下 [Java 内存区域详解](https://javaguide.cn/java/jvm/memory-area.html) 这篇文章。
@@ -708,7 +708,7 @@ System.out.println(aa==bb);// true
708708
709709
会创建 12 个字符串对象。
710710
711-
1、如果字符串常量池中不存在字符串对象“abc”的引用,那么它会在堆上创建两个字符串对象,其中一个字符串对象的引用会被保存在字符串常量池中。
711+
1、如果字符串常量池中不存在字符串对象 “abc”,那么它首先会在字符串常量池中创建字符串对象 "abc",然后在堆内存中再创建其中一个字符串对象 "abc"
712712
713713
示例代码(JDK 1.8):
714714
@@ -720,14 +720,14 @@ String s1 = new String("abc");
720720
721721
![](https://oss.javaguide.cn/github/javaguide/open-source-project/image-20220413175809959.png)
722722
723-
`ldc` 命令用于判断字符串常量池中是否保存了对应的字符串对象的引用,如果保存了的话直接返回,如果没有保存的话,会在堆中创建对应的字符串对象并将该字符串对象的引用保存到字符串常量池中
723+
`ldc (load constant)` 指令的作用是从常量池中加载常量,包括字符串常量、整数常量、浮点数常量、或者类引用。这里用于判断字符串常量池中是否保存了对应的字符串对象,如果保存了的话会将它的引用加载到操作数栈,如果没有保存的话,会在字符串常量池中创建对应的字符串对象,并将其引用加载到操作数栈中
724724
725-
2、如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”。
725+
2、如果字符串常量池中已存在字符串对象“abc”,则只会在堆中创建 1 个字符串对象“abc”。
726726
727727
示例代码(JDK 1.8):
728728
729729
```java
730-
// 字符串常量池中已存在字符串对象“abc”的引用
730+
// 字符串常量池中已存在字符串对象“abc”
731731
String s1 = "abc";
732732
// 下面这段代码只会在堆中创建 1 个字符串对象“abc”
733733
String s2 = new String("abc");

docs/java/basis/java-basic-questions-03.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ SPI 将服务接口和具体的服务实现分离开来,将服务调用方和
451451

452452
简单来说:
453453

454-
- **序列化**将数据结构或对象转换成二进制字节流的过程
455-
- **反序列化**将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程
454+
- **序列化**将数据结构或对象转换成可以存储或传输的形式,通常是二进制字节流,也可以是 JSON, XML 等文本格式
455+
- **反序列化**将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程
456456

457457
对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。
458458

docs/java/basis/serialization.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ tag:
1111

1212
简单来说:
1313

14-
- **序列化**将数据结构或对象转换成二进制字节流的过程
15-
- **反序列化**将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程
14+
- **序列化**将数据结构或对象转换成可以存储或传输的形式,通常是二进制字节流,也可以是 JSON, XML 等文本格式
15+
- **反序列化**将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程
1616

1717
对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。
1818

docs/java/jvm/jvm-garbage-collection.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ JDK1.2 以后,Java 对引用的概念进行了扩充,将引用分为强引
353353
354354
当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将 Java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。
355355
356-
比如在新生代中,每次收集都会有大量对象死去,所以可以选择“标记-复制”算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。
356+
比如在新生代中,每次收集都会有大量对象死去,所以可以选择“复制”算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。而老年代的对象存活几率是比较高的,而且没有额外的空间对它进行分配担保,所以我们必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。
357357
358358
**延伸面试问题:** HotSpot 为什么要分为新生代和老年代?
359359

docs/java/jvm/memory-area.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,12 @@ Class 文件中除了有类的版本、字段、方法、接口等描述信息
242242
**字符串常量池** 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
243243
244244
```java
245-
// 在堆中创建字符串对象”ab“
246-
// 将字符串对象”ab“的引用保存在字符串常量池中
245+
// 在字符串常量池中创建字符串对象 ”ab“
246+
// 将字符串对象 ”ab“ 的引用赋值给给 aa
247247
String aa = "ab";
248-
// 直接返回字符串常量池中字符串对象”ab“的引用
248+
// 直接返回字符串常量池中字符串对象 ”ab“,赋值给引用 bb
249249
String bb = "ab";
250-
System.out.println(aa==bb);// true
250+
System.out.println(aa==bb); // true
251251
```
252252
253253
HotSpot 虚拟机中字符串常量池的实现是 `src/hotspot/share/classfile/stringTable.cpp` ,`StringTable` 可以简单理解为一个固定大小的`HashTable` ,容量为 `StringTableSize`(可以通过 `-XX:StringTableSize` 参数来设置),保存的是字符串(key)和 字符串对象的引用(value)的映射关系,字符串对象的引用指向堆中的字符串对象。

0 commit comments

Comments
 (0)