Merge branch 'main' of https://github.com/MarlonDML/JavaGuide
@ -18,7 +18,7 @@ MySQL 字符编码集中有两套 UTF-8 编码实现:**`utf8`** 和 **`utf8mb4
|
||||
|
||||
**计算机只能存储二进制的数据,那英文、汉字、表情等字符应该如何存储呢?**
|
||||
|
||||
我们要将这些字符和二级制的数据一一对应起来,比如说字符“a”对应“01100001”,反之,“01100001”对应 “a”。我们将字符对应二进制数据的过程称为"**字符编码**",反之,二进制数据解析成字符的过程称为“**字符解码**”。
|
||||
我们要将这些字符和二进制的数据一一对应起来,比如说字符“a”对应“01100001”,反之,“01100001”对应 “a”。我们将字符对应二进制数据的过程称为"**字符编码**",反之,二进制数据解析成字符的过程称为“**字符解码**”。
|
||||
|
||||
## 有哪些常见的字符集?
|
||||
|
||||
|
@ -50,7 +50,7 @@ Paxos 算法是 Leslie Lamport([莱斯利·兰伯特](https://zh.wikipedia.org
|
||||
|
||||
- Paxos 算法是兰伯特在 **1990** 年提出了一种分布式系统共识算法。
|
||||
- 兰伯特当时提出的 Paxos 算法主要包含 2 个部分:Basic Paxos 算法和Multi-Paxos 思想。
|
||||
- Raft 算法、ZAB 协议、 Fast Paxos 算法都是基于 Paxos 算法改进而来。。
|
||||
- Raft 算法、ZAB 协议、 Fast Paxos 算法都是基于 Paxos 算法改进而来。
|
||||
|
||||
## 一致性(Consistency)与共识(Consensus)
|
||||
|
||||
|
BIN
docs/java/basis/images/oracle-jdk-release-cadence.jpg
Normal file
After Width: | Height: | Size: 179 KiB |
@ -87,15 +87,34 @@ JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有
|
||||
>
|
||||
> 答:非常接近 - 我们的 Oracle JDK 版本构建过程基于 OpenJDK 7 构建,只添加了几个部分,例如部署代码,其中包括 Oracle 的 Java 插件和 Java WebStart 的实现,以及一些闭源的第三方组件,如图形光栅化器,一些开源的第三方组件,如 Rhino,以及一些零碎的东西,如附加文档或第三方字体。展望未来,我们的目的是开源 Oracle JDK 的所有部分,除了我们考虑商业功能的部分。
|
||||
|
||||
**总结:**
|
||||
**总结:**(提示:下面括号内的内容是基于原文补充说明的,因为原文太过于晦涩难懂,用人话重新解释了下,如果你看得懂里面的术语,可以忽略括号解释的内容)
|
||||
|
||||
1. Oracle JDK 大概每 6 个月发一次主要版本(从 2014 年 3 月 JDK 8 LTS 发布到 2017 年 9 月 JDK 9 发布经历了长达 3 年多的时间,所以并不总是 6 个月),而 OpenJDK 版本大概每三个月发布一次。但这不是固定的,我觉得了解这个没啥用处。详情参见:[https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence](https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence) 。
|
||||
|
||||
2. OpenJDK 是一个参考模型并且是完全开源的,而 Oracle JDK 是 OpenJDK 的一个实现,并不是完全开源的;(个人观点:众所周知,JDK 原来是 SUN 公司开发的,后来 SUN 公司又卖给了 Oracle 公司,Oracle 公司以 Oracle 数据库而著名,而 Oracle 数据库又是闭源的,这个时候 Oracle 公司就不想完全开源了,但是原来的 SUN 公司又把 JDK 给开源了,如果这个时候 Oracle 收购回来之后就把他给闭源,必然会引其很多 Java 开发者的不满,导致大家对 Java 失去信心,那 Oracle 公司收购回来不就把 Java 烂在手里了吗!然后,Oracle 公司就想了个骚操作,这样吧,我把一部分核心代码开源出来给你们玩,并且我要和你们自己搞的 JDK 区分下,你们叫 OpenJDK,我叫 Oracle JDK,我发布我的,你们继续玩你们的,要是你们搞出来什么好玩的东西,我后续发布 Oracle JDK 也会拿来用一下,一举两得!)OpenJDK 开源项目:[https://github.com/openjdk/jdk](https://github.com/openjdk/jdk)
|
||||
|
||||
3. Oracle JDK 比 OpenJDK 更稳定(肯定啦,Oracle JDK 由 Oracle 内部团队进行单独研发的,而且发布时间不 OpenJDK 更长,质量更有保障)。OpenJDK 和 Oracle JDK 的代码几乎相同(OpenJDK 的代码是从 Oracle JDK 代码派生出来的,可以理解为在 Oracle JDK 分支上拉了一条新的分支叫 OpenJDK,所以大部分代码相同),但 Oracle JDK 有更多的类和一些错误修复。因此,如果您想开发企业/商业软件,我建议您选择 Oracle JDK,因为它经过了彻底的测试和稳定。某些情况下,有些人提到在使用 OpenJDK 可能会遇到了许多应用程序崩溃的问题,但是,只需切换到 Oracle JDK 就可以解决问题;
|
||||
|
||||
1. Oracle JDK 大概每 6 个月发一次主要版本,而 OpenJDK 版本大概每三个月发布一次。但这不是固定的,我觉得了解这个没啥用处。详情参见:[https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence](https://blogs.oracle.com/java-platform-group/update-and-faq-on-the-java-se-release-cadence) 。
|
||||
2. OpenJDK 是一个参考模型并且是完全开源的,而 Oracle JDK 是 OpenJDK 的一个实现,并不是完全开源的;
|
||||
3. Oracle JDK 比 OpenJDK 更稳定。OpenJDK 和 Oracle JDK 的代码几乎相同,但 Oracle JDK 有更多的类和一些错误修复。因此,如果您想开发企业/商业软件,我建议您选择 Oracle JDK,因为它经过了彻底的测试和稳定。某些情况下,有些人提到在使用 OpenJDK 可能会遇到了许多应用程序崩溃的问题,但是,只需切换到 Oracle JDK 就可以解决问题;
|
||||
4. 在响应性和 JVM 性能方面,Oracle JDK 与 OpenJDK 相比提供了更好的性能;
|
||||
5. Oracle JDK 不会为即将发布的版本提供长期支持,用户每次都必须通过更新到最新版本获得支持来获取最新版本;
|
||||
|
||||
5. Oracle JDK 不会为即将发布的版本提供长期支持(如果是 LTS 长期支持版本的话也会,比如 JDK 8,但并不是每个版本都是 LTS 版本),用户每次都必须通过更新到最新版本获得支持来获取最新版本;
|
||||
|
||||
6. Oracle JDK 使用 BCL/OTN 协议获得许可,而 OpenJDK 根据 GPL v2 许可获得许可。
|
||||
|
||||
>既然 Oracle JDK 这么好,那为什么还要有 OpenJDK?
|
||||
>
|
||||
>答:
|
||||
>
|
||||
>1. OpenJDK 是开源的,开源意味着你可以对它根据你自己的需要进行修改、优化,比如 Alibaba 基于 OpenJDK 开发了 Dragonwell8:[https://github.com/alibaba/dragonwell8](https://github.com/alibaba/dragonwell8)
|
||||
>
|
||||
>2. OpenJDK 是商业免费的(这也是为什么通过 yum 包管理器上默认安装的 JDK 是 OpenJDK 而不是 Oracle JDK)。虽然 Oracle JDK 也是商业免费(比如 JDK 8),但并不是所有版本都是免费的。
|
||||
>
|
||||
>3. OpenJDK 更新频率更快。Oracle JDK 一般是每 6 个月发布一个新版本,而 OpenJDK 一般是每 3 个月发布一个新版本。(现在你知道为啥 Oracle JDK 更稳定了吧,先在 OpenJDK 试试水,把大部分问题都解决掉了才在 Oracle JDK 上发布)
|
||||
>
|
||||
> 基于以上这些原因,OpenJDK 还是有存在的必要的!
|
||||
|
||||

|
||||
|
||||
🌈 拓展一下:
|
||||
|
||||
- BCL 协议(Oracle Binary Code License Agreement): 可以使用 JDK(支持商用),但是不能进行修改。
|
||||
|
@ -211,7 +211,7 @@ System.out.println(person1.getAddress() == person1Copy.getAddress());
|
||||
|
||||

|
||||
|
||||
## Java 常见对象
|
||||
## Java 常见类
|
||||
|
||||
### Object
|
||||
|
||||
@ -520,50 +520,88 @@ System.out.println(s);
|
||||
**字符串常量池** 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
|
||||
|
||||
```java
|
||||
String aa = "ab"; // 放在常量池中
|
||||
String bb = "ab"; // 从常量池中查找
|
||||
// 在堆中创建字符串对象”ab“
|
||||
// 将字符串对象”ab“的引用保存在字符串常量池中
|
||||
String aa = "ab";
|
||||
// 直接返回字符串常量池中字符串对象”ab“的引用
|
||||
String bb = "ab";
|
||||
System.out.println(aa==bb);// true
|
||||
```
|
||||
|
||||
JDK1.7 之前运行时常量池逻辑包含字符串常量池存放在方法区。JDK1.7 的时候,字符串常量池被从方法区拿到了堆中。
|
||||
|
||||
你可以在 JVM 部分找到更多关于字符串常量池的介绍。
|
||||
更多关于字符串常量池的介绍可以看一下 [Java 内存区域详解](https://javaguide.cn/java/jvm/memory-area.html) 这篇文章。
|
||||
|
||||
#### String s1 = new String("abc");这句话创建了几个字符串对象?
|
||||
|
||||
会创建 1 或 2 个字符串:
|
||||
会创建 1 或 2 个字符串。
|
||||
|
||||
- 如果字符串常量池中已存在字符串常量“abc”,则只会在堆空间创建一个字符串常量“abc”。
|
||||
- 如果字符串常量池中没有字符串常量“abc”,那么它将首先在字符串常量池中创建,然后在堆空间中创建,因此将创建总共 2 个字符串对象。
|
||||
1、如果字符串常量池中不存在字符串对象“abc”的引用,那么会在堆中创建 2 个字符串对象“abc”。
|
||||
|
||||
**验证** :
|
||||
示例代码(JDK 1.8):
|
||||
|
||||
```java
|
||||
String s1 = new String("abc");// 堆内存的地址值
|
||||
String s2 = "abc";
|
||||
System.out.println(s1 == s2);// 输出 false,因为一个是堆内存,一个是常量池的内存,故两者是不同的。
|
||||
System.out.println(s1.equals(s2));// 输出 true
|
||||
String s1 = new String("abc");
|
||||
```
|
||||
|
||||
**结果** :
|
||||
对应的字节码:
|
||||
|
||||

|
||||
|
||||
`ldc` 命令用于判断字符串常量池中是否保存了对应的字符串对象的引用,如果保存了的话直接返回,如果没有保存的话,会在堆中创建对应的字符串对象并将该字符串对象的引用保存到字符串常量池中。
|
||||
|
||||
2、如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”。
|
||||
|
||||
示例代码(JDK 1.8):
|
||||
|
||||
```java
|
||||
// 字符串常量池中已存在字符串对象“abc”的引用
|
||||
String s1 = "abc";
|
||||
// 下面这段代码只会在堆中创建 1 个字符串对象“abc”
|
||||
String s2 = new String("abc");
|
||||
```
|
||||
false
|
||||
true
|
||||
|
||||
对应的字节码:
|
||||
|
||||

|
||||
|
||||
这里就不对上面的字节码进行详细注释了,7 这个位置的 `ldc` 命令不会在堆中创建新的字符串对象“abc”,这是因为 0 这个位置已经执行了一次 `ldc` 命令,已经在堆中创建过一次字符串对象“abc”了。7 这个位置执行 `ldc` 命令会直接返回字符串常量池中字符串对象“abc”对应的引用。
|
||||
|
||||
#### intern 方法有什么作用?
|
||||
|
||||
`String.intern()` 是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况:
|
||||
|
||||
- 如果字符串常量池中保存了对应的字符串对象的引用,就直接返回该引用。
|
||||
- 如果字符串常量池中没有保存了对应的字符串对象的引用,那就在常量池中创建一个指向该字符串对象的引用并返回。
|
||||
|
||||
示例代码(JDK 1.8) :
|
||||
|
||||
```java
|
||||
// 在堆中创建字符串对象”Java“
|
||||
// 将字符串对象”Java“的引用保存在字符串常量池中
|
||||
String s1 = "Java";
|
||||
// 直接返回字符串常量池中字符串对象”Java“对应的引用
|
||||
String s2 = s1.intern();
|
||||
// 会在堆中在单独创建一个字符串对象
|
||||
String s3 = new String("Java");
|
||||
// 直接返回字符串常量池中字符串对象”Java“对应的引用
|
||||
String s4 = s3.intern();
|
||||
// s1 和 s2 指向的是堆中的同一个对象
|
||||
System.out.println(s1 == s2); // true
|
||||
// s3 和 s4 指向的是堆中不同的对象
|
||||
System.out.println(s3 == s4); // false
|
||||
// s1 和 s4 指向的是堆中不同的对象
|
||||
System.out.println(s1 == s4); //true
|
||||
```
|
||||
|
||||
#### String 类型的变量和常量做“+”运算时发生了什么?
|
||||
|
||||
一个非常常见的面试题。
|
||||
|
||||
先来看字符串不加 `final` 关键字拼接的情况(JDK1.8):
|
||||
|
||||
```java
|
||||
String str1 = "str";
|
||||
String str2 = "ing";
|
||||
String str3 = "str" + "ing";//常量池中的对象
|
||||
String str4 = str1 + str2; //在堆上创建的新的对象
|
||||
String str5 = "string";//常量池中的对象
|
||||
String str3 = "str" + "ing";
|
||||
String str4 = str1 + str2;
|
||||
String str5 = "string";
|
||||
System.out.println(str3 == str4);//false
|
||||
System.out.println(str3 == str5);//true
|
||||
System.out.println(str4 == str5);//false
|
||||
@ -573,39 +611,23 @@ System.out.println(str4 == str5);//false
|
||||
|
||||

|
||||
|
||||
> 对于基本数据类型来说,== 比较的是值。对于引用数据类型来说,==比较的是对象的内存地址。
|
||||
**对于编译期可以确定值的字符串,也就是常量字符串 ,jvm 会将其存入字符串常量池。并且,字符串常量拼接得到的字符串常量在编译阶段就已经被存放字符串常量池,这个得益于编译器的优化。**
|
||||
|
||||
对于编译期可以确定值的字符串,也就是常量字符串 ,jvm 会将其存入字符串常量池。
|
||||
在编译过程中,Javac 编译器(下文中统称为编译器)会进行一个叫做 **常量折叠(Constant Folding)** 的代码优化。《深入理解 Java 虚拟机》中是也有介绍到:
|
||||
|
||||
> **字符串常量池** 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
|
||||
>
|
||||
> ```java
|
||||
> String aa = "ab"; // 放在常量池中
|
||||
> String bb = "ab"; // 从常量池中查找
|
||||
> System.out.println(aa==bb);// true
|
||||
> ```
|
||||
>
|
||||
> JDK1.7 之前运行时常量池逻辑包含字符串常量池存放在方法区。JDK1.7 的时候,字符串常量池被从方法区拿到了堆中。
|
||||

|
||||
|
||||
并且,字符串常量拼接得到的字符串常量在编译阶段就已经被存放字符串常量池,这个得益于编译器的优化。
|
||||
常量折叠会把常量表达式的值求出来作为常量嵌在最终生成的代码中,这是 Javac 编译器会对源代码做的极少量优化措施之一(代码优化几乎都在即时编译器中进行)。
|
||||
|
||||
> 在编译过程中,Javac 编译器(下文中统称为编译器)会进行一个叫做 **常量折叠(Constant Folding)** 的代码优化。《深入理解 Java 虚拟机》中是也有介绍到:
|
||||
>
|
||||
> 
|
||||
>
|
||||
> 常量折叠会把常量表达式的值求出来作为常量嵌在最终生成的代码中,这是 Javac 编译器会对源代码做的极少量优化措施之一(代码优化几乎都在即时编译器中进行)。
|
||||
>
|
||||
> 对于 `String str3 = "str" + "ing";` 编译器会给你优化成 `String str3 = "string";` 。
|
||||
>
|
||||
> 并不是所有的常量都会进行折叠,只有编译器在程序编译期就可以确定值的常量才可以:
|
||||
>
|
||||
> - 基本数据类型( `byte`、`boolean`、`short`、`char`、`int`、`float`、`long`、`double`)以及字符串常量。
|
||||
> - `final` 修饰的基本数据类型和字符串变量
|
||||
> - 字符串通过 “+”拼接得到的字符串、基本数据类型之间算数运算(加减乘除)、基本数据类型的位运算(<<、\>>、\>>> )
|
||||
对于 `String str3 = "str" + "ing";` 编译器会给你优化成 `String str3 = "string";` 。
|
||||
|
||||
因此,`str1` 、 `str2` 、 `str3` 都属于字符串常量池中的对象。
|
||||
并不是所有的常量都会进行折叠,只有编译器在程序编译期就可以确定值的常量才可以:
|
||||
|
||||
引用的值在程序编译期是无法确定的,编译器无法对其进行优化。
|
||||
- 基本数据类型( `byte`、`boolean`、`short`、`char`、`int`、`float`、`long`、`double`)以及字符串常量。
|
||||
- `final` 修饰的基本数据类型和字符串变量
|
||||
- 字符串通过 “+”拼接得到的字符串、基本数据类型之间算数运算(加减乘除)、基本数据类型的位运算(<<、\>>、\>>> )
|
||||
|
||||
**引用的值在程序编译期是无法确定的,编译器无法对其进行优化。**
|
||||
|
||||
对象引用和“+”的字符串拼接方式,实际上是通过 `StringBuilder` 调用 `append()` 方法实现的,拼接完成之后调用 `toString()` 得到一个 `String` 对象 。
|
||||
|
||||
@ -613,16 +635,12 @@ System.out.println(str4 == str5);//false
|
||||
String str4 = new StringBuilder().append(str1).append(str2).toString();
|
||||
```
|
||||
|
||||
因此,`str4` 并不是字符串常量池中存在的对象,属于堆上的新对象。
|
||||
|
||||
我画了一个图帮助理解:
|
||||
|
||||

|
||||
|
||||
我们在平时写代码的时候,尽量避免多个字符串对象拼接,因为这样会重新创建对象。如果需要改变字符串的话,可以使用 `StringBuilder` 或者 `StringBuffer`。
|
||||
|
||||
不过,字符串使用 `final` 关键字声明之后,可以让编译器当做常量来处理。
|
||||
|
||||
示例代码:
|
||||
|
||||
```java
|
||||
final String str1 = "str";
|
||||
final String str2 = "ing";
|
||||
@ -636,7 +654,7 @@ System.out.println(c == d);// true
|
||||
|
||||
如果 ,编译器在运行时才能知道其确切值的话,就无法对其优化。
|
||||
|
||||
示例代码如下(`str2` 在运行时才能确定其值):
|
||||
示例代码(`str2` 在运行时才能确定其值):
|
||||
|
||||
```java
|
||||
final String str1 = "str";
|
||||
@ -649,83 +667,6 @@ public static String getStr() {
|
||||
}
|
||||
```
|
||||
|
||||
**我们再来看一个类似的问题!**
|
||||
|
||||
```java
|
||||
String str1 = "abcd";
|
||||
String str2 = new String("abcd");
|
||||
String str3 = new String("abcd");
|
||||
System.out.println(str1==str2);
|
||||
System.out.println(str2==str3);
|
||||
```
|
||||
|
||||
上面的代码运行之后会输出什么呢?
|
||||
|
||||
答案是:
|
||||
|
||||
```
|
||||
false
|
||||
false
|
||||
```
|
||||
|
||||
**这是为什么呢?**
|
||||
|
||||
我们先来看下面这种创建字符串对象的方式:
|
||||
|
||||
```java
|
||||
// 从字符串常量池中拿对象
|
||||
String str1 = "abcd";
|
||||
```
|
||||
|
||||
这种情况下,jvm 会先检查字符串常量池中有没有"abcd",如果字符串常量池中没有,则创建一个,然后 str1 指向字符串常量池中的对象,如果有,则直接将 str1 指向"abcd";
|
||||
|
||||
因此,`str1` 指向的是字符串常量池的对象。
|
||||
|
||||
我们再来看下面这种创建字符串对象的方式:
|
||||
|
||||
```java
|
||||
// 直接在堆内存空间创建一个新的对象。
|
||||
String str2 = new String("abcd");
|
||||
String str3 = new String("abcd");
|
||||
```
|
||||
|
||||
**只要使用 new 的方式创建对象,便需要创建新的对象** 。
|
||||
|
||||
使用 new 的方式创建对象的方式如下,可以简单概括为 3 步:
|
||||
|
||||
1. 在堆中创建一个字符串对象
|
||||
2. 检查字符串常量池中是否有和 new 的字符串值相等的字符串常量
|
||||
3. 如果没有的话需要在字符串常量池中也创建一个值相等的字符串常量,如果有的话,就直接返回堆中的字符串实例对象地址。
|
||||
|
||||
因此,`str2` 和 `str3` 都是在堆中新创建的对象。
|
||||
|
||||
**字符串常量池比较特殊,它的主要使用方法有两种:**
|
||||
|
||||
1. 直接使用双引号声明出来的 `String` 对象会直接存储在常量池中。
|
||||
2. 如果不是用双引号声明的 `String` 对象,使用 `String` 提供的 `intern()` 方法也有同样的效果。`String.intern()` 是一个 Native 方法,它的作用是:如果字符串常量池中已经包含一个等于此 String 对象内容的字符串,则返回常量池中该字符串的引用;如果没有,JDK1.7 之前(不包含 1.7)的处理方式是在常量池中创建与此 `String` 内容相同的字符串,并返回常量池中创建的字符串的引用,JDK1.7 以及之后,字符串常量池被从方法区拿到了堆中,jvm 不会在常量池中创建该对象,而是将堆中这个对象的引用直接放到常量池中,减少不必要的内存开销。
|
||||
|
||||
示例代码如下(JDK 1.8) :
|
||||
|
||||
```java
|
||||
String s1 = "Javatpoint";
|
||||
String s2 = s1.intern();
|
||||
String s3 = new String("Javatpoint");
|
||||
String s4 = s3.intern();
|
||||
System.out.println(s1==s2); // True
|
||||
System.out.println(s1==s3); // False
|
||||
System.out.println(s1==s4); // True
|
||||
System.out.println(s2==s3); // False
|
||||
System.out.println(s2==s4); // True
|
||||
System.out.println(s3==s4); // False
|
||||
```
|
||||
|
||||
**总结** :
|
||||
|
||||
1. 对于基本数据类型来说,==比较的是值。对于引用数据类型来说,==比较的是对象的内存地址。
|
||||
2. 在编译过程中,Javac 编译器(下文中统称为编译器)会进行一个叫做 **常量折叠(Constant Folding)** 的代码优化。常量折叠会把常量表达式的值求出来作为常量嵌在最终生成的代码中,这是 Javac 编译器会对源代码做的极少量优化措施之一(代码优化几乎都在即时编译器中进行)。
|
||||
3. 一般来说,我们要尽量避免通过 new 的方式创建字符串。使用双引号声明的 `String` 对象( `String s1 = "java"` )更利于让编译器有机会优化我们的代码,同时也更易于阅读。
|
||||
4. 被 `final` 关键字修改之后的 `String` 会被编译器当做常量来处理,编译器程序编译期就可以确定它的值,其效果就相当于访问常量。
|
||||
|
||||
## 参考
|
||||
|
||||
- 深入解析 String#intern<https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html>
|
||||
|
@ -82,9 +82,15 @@ Java 集合框架如下图所示:
|
||||
2. **底层数据结构:** `Arraylist` 底层使用的是 **`Object` 数组**;`LinkedList` 底层使用的是 **双向链表** 数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环。注意双向链表和双向循环链表的区别,下面有介绍到!)
|
||||
3. **插入和删除是否受元素位置的影响:**
|
||||
- `ArrayList` 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行`add(E e)`方法的时候, `ArrayList` 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(`add(int index, E element)`)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。
|
||||
- `LinkedList` 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响(`add(E e)`、`addFirst(E e)`、`addLast(E e)`、`removeFirst()` 、 `removeLast()`),近似 O(1),如果是要在指定位置 `i` 插入和删除元素的话(`add(int index, E element)`,`remove(Object o)`) 时间复杂度近似为 O(n) ,因为需要先移动到指定位置再插入。
|
||||
- `LinkedList` 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响(`add(E e)`、`addFirst(E e)`、`addLast(E e)`、`removeFirst()` 、 `removeLast()`),时间复杂度为 O(1),如果是要在指定位置 `i` 插入和删除元素的话(`add(int index, E element)`,`remove(Object o)`), 时间复杂度为 O(n) ,因为需要先移动到指定位置再插入。
|
||||
4. **是否支持快速随机访问:** `LinkedList` 不支持高效的随机元素访问,而 `ArrayList` 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于`get(int index)`方法)。
|
||||
5. **内存空间占用:** ArrayList 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。
|
||||
5. **内存空间占用:** `ArrayList` 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。
|
||||
|
||||
我们在项目中一般是不会使用到 `LinkedList` 的,需要用到 `LinkedList` 的场景几乎都可以使用 `ArrayList` 来代替,并且,性能通常会更好!就连 `LinkedList` 的作者约书亚 · 布洛克(Josh Bloch)自己都说从来不会使用 `LinkedList` 。
|
||||
|
||||

|
||||
|
||||
另外,不要下意识地认为 `LinkedList` 作为链表就最适合元素增删的场景。我在上面也说了,`LinkedList` 仅仅在头尾插入或者删除元素的时候时间复杂度近似 O(1),其他情况增删元素的时间复杂度都是 O(n) 。
|
||||
|
||||
#### 补充内容:双向链表和双向循环链表
|
||||
|
||||
|
@ -155,7 +155,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作 **GC 堆(
|
||||
|
||||
当虚拟机要使用一个类时,它需要读取并解析 Class 文件获取相关信息,再将信息存入到方法区。方法区会存储已被虚拟机加载的 **类信息、字段信息、方法信息、常量、静态变量、即时编译器编译后的代码缓存等数据**。
|
||||
|
||||
**方法区和永久代以及元空间是什么关系呢?** 方法区和永久代以及元空间的关系很像 Java 中接口和类的关系,类实现了接口,这里的类就可以看作是永久代和元空间,接口可以看作是方法区,也就是说永久代以及元空间是 HotSpot 虚拟机对虚拟机规范中方法区的两种实现方式。并且,永久代是 JDK 1.8 之前的方法区实现,JDK 1.8 及以后方法区的实现便成为元空间。
|
||||
**方法区和永久代以及元空间是什么关系呢?** 方法区和永久代以及元空间的关系很像 Java 中接口和类的关系,类实现了接口,这里的类就可以看作是永久代和元空间,接口可以看作是方法区,也就是说永久代以及元空间是 HotSpot 虚拟机对虚拟机规范中方法区的两种实现方式。并且,永久代是 JDK 1.8 之前的方法区实现,JDK 1.8 及以后方法区的实现变成了元空间。
|
||||
|
||||

|
||||
|
||||
@ -195,51 +195,42 @@ JDK 1.8 的时候,方法区(HotSpot 的永久代)被彻底移除了(JDK1
|
||||
|
||||
与永久代很大的不同就是,如果不指定大小的话,随着更多类的创建,虚拟机会耗尽所有可用的系统内存。
|
||||
|
||||
最后,我画了 3 张图带你看看 JDK1.6 到 JDK1.8 方法区的变化。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
多提一嘴,为了完善方法区这部分内容的介绍,我看了很多文档,还特意去扒了一下《深入理解Java虚拟机(第3版)》勘误的 issues,简直看到的脑壳疼。。。
|
||||
|
||||

|
||||
|
||||
讲真,深挖下来的话细节太多,也没太大意义(卷不动了),我上面讲到的这些基本就够面试使用了。
|
||||
|
||||
### 运行时常量池
|
||||
|
||||
Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有用于存放编译期生成的各种字面量(Literal)和符号引用(Symbolic Reference)的常量池表(Constant Pool Table)。常量池表会在类加载后存放到方法区的运行时常量池中。
|
||||
Class 文件中除了有类的版本、字段、方法、接口等描述信息外,还有用于存放编译期生成的各种字面量(Literal)和符号引用(Symbolic Reference)的 **常量池表(Constant Pool Table)** 。
|
||||
|
||||
字面量是源代码中的固定值的表示法,即通过字面我们就能知道其值的含义。字面量包括整数、浮点数和字符串字面量,符号引用包括类符号引用、字段符号引用、方法符号引用和接口方法符号引用。
|
||||
|
||||
常量池表会在类加载后存放到方法区的运行时常量池中。
|
||||
|
||||
运行时常量池的功能类似于传统编程语言的符号表,尽管它包含了比典型符号表更广泛的数据。
|
||||
|
||||
既然运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会抛出 `OutOfMemoryError` 错误。
|
||||
|
||||
~~**JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。**~~
|
||||
|
||||
> **🐛 修正(参见:[issue747](https://github.com/Snailclimb/JavaGuide/issues/747),[reference](https://blog.csdn.net/q5706503/article/details/84640762))** :
|
||||
>
|
||||
> 1. JDK1.7 之前,运行时常量池包含的字符串常量池和静态变量存放在方法区, 此时 HotSpot 虚拟机对方法区的实现为永久代。
|
||||
> 2. JDK1.7 字符串常量池和静态变量被从方法区拿到了堆中, 这里没有提到运行时常量池,也就是说字符串常量池被单独拿到堆,运行时常量池剩下的东西还在方法区, 也就是 HotSpot 中的永久代 。
|
||||
> 3. JDK1.8 HotSpot 移除了永久代用元空间(Metaspace)取而代之, 这时候字符串常量池和静态变量还在堆, 运行时常量池还在方法区, 只不过方法区的实现从永久代变成了元空间(Metaspace)
|
||||
|
||||
**字符串常量池有什么作用?**
|
||||
### 字符串常量池
|
||||
|
||||
**字符串常量池** 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
|
||||
|
||||
```java
|
||||
String aa = "ab"; // 放在常量池中
|
||||
String bb = "ab"; // 从常量池中查找
|
||||
// 在堆中创建字符串对象”ab“
|
||||
// 将字符串对象”ab“的引用保存在字符串常量池中
|
||||
String aa = "ab";
|
||||
// 直接返回字符串常量池中字符串对象”ab“的引用
|
||||
String bb = "ab";
|
||||
System.out.println(aa==bb);// true
|
||||
```
|
||||
|
||||
JDK1.7 之前运行时常量池逻辑包含字符串常量池存放在方法区。JDK1.7 的时候,字符串常量池被从方法区拿到了堆中。
|
||||
HotSpot 虚拟机中字符串常量池的实现是 `src/hotspot/share/classfile/stringTable.cpp` ,`StringTable` 本质上就是一个`HashSet<String>` ,容量为 `StringTableSize`(可以通过 `-XX:StringTableSize` 参数来设置)。
|
||||
|
||||
这里的字符串其实就是我们前面提到的字符串字面量。在声明一个字符串字面量时,如果字符串常量池中能够找到该字符串字面量,则直接返回该引用。如果找不到的话,则在常量池中创建该字符串字面量的对象并返回其引用。
|
||||
**`StringTable` 中保存的是字符串对象的引用,字符串对象的引用指向堆中的字符串对象。**
|
||||
|
||||
JDK1.7 之前,字符串常量池存放在永久代。JDK1.7 字符串常量池和静态变量从永久代移动了 Java 堆中。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
**JDK 1.7 为什么要将字符串常量池移动到堆中?**
|
||||
|
||||
@ -247,6 +238,10 @@ JDK1.7 之前运行时常量池逻辑包含字符串常量池存放在方法区
|
||||
|
||||
相关问题:[JVM 常量池中存储的是对象还是引用呢? - RednaxelaFX - 知乎](https://www.zhihu.com/question/57109429/answer/151717241)
|
||||
|
||||
最后再来分享一段周志明老师在[《深入理解 Java 虚拟机(第 3 版)》样例代码&勘误](https://github.com/fenixsoft/jvm_book) Github 仓库的 [issue#112](https://github.com/fenixsoft/jvm_book/issues/112) 中说过的话:
|
||||
|
||||
> **运行时常量池、方法区、字符串常量池这些都是不随虚拟机实现而改变的逻辑概念,是公共且抽象的,Metaspace、Heap 是与具体某种虚拟机实现相关的物理概念,是私有且具体的。**
|
||||
|
||||
### 直接内存
|
||||
|
||||
直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 错误出现。
|
||||
@ -337,6 +332,8 @@ Java 对象的创建过程我建议最好是能默写出来,并且要掌握每
|
||||
- 《自己动手写 Java 虚拟机》
|
||||
- Chapter 2. The Structure of the Java Virtual Machine:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html
|
||||
- JVM 栈帧内部结构-动态链接:https://chenxitag.com/archives/368
|
||||
- Java 中 new String("字面量") 中 "字面量" 是何时进入字符串常量池的? - 木女孩的回答 - 知乎: https://www.zhihu.com/question/55994121/answer/147296098
|
||||
- JVM 常量池中存储的是对象还是引用呢? - RednaxelaFX 的回答 - 知乎: https://www.zhihu.com/question/57109429/answer/151717241
|
||||
- <http://www.pointsoftware.ch/en/under-the-hood-runtime-data-areas-javas-memory-model/>
|
||||
- <https://dzone.com/articles/jvm-permgen-%E2%80%93-where-art-thou>
|
||||
- <https://stackoverflow.com/questions/9095748/method-area-and-permgen>
|
||||
|
BIN
docs/java/jvm/method-area-jdk1.6.png
Normal file
After Width: | Height: | Size: 561 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 67 KiB |
@ -1 +0,0 @@
|
||||
<mxfile host="Electron" modified="2022-03-30T07:19:12.575Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="A72fQ9o6pTmrxFVRr5fa" version="13.4.5" type="device"><diagram id="SNS0W3kPdRRnqGH8hLX1" name="Page-1">7Vptb5tIEP41K919cAUsrx/BxmlS3am6nJp+O61hMSgYHIzjpL/+ZpbFBrO+pDrbcdM6kbzM7AvMM8/M7GJCx4unq4ot0z/KmOfE0OInQifEMHRds+ELJc+NxPOcRjCvslh22glus29cCjUpXWcxX/U61mWZ19myL4zKouBR3ZOxqio3/W5JmfdXXbI5HwhuI5YPpXdZXKeN1DWcnfwjz+Zpu7Jue41mwdrO8klWKYvLTUdEQ0LHVVnWTWvxNOY5Gq+1SzNuekC7vbGKF/VrBnz9Gq4/Ltk1+8LvJqX/kH3+yxqZzSyPLF/LB5Y3Wz+3FqjKdRFznEQnNNikWc1vlyxC7QYwB1laL3KpTrI8H5d5WYmxNLHwD+SruirveUdjiw9q7nkdpe3wsqilD8DTNNedQc0H5MNnl+Z45FXNnzoiaYsrXi54XT1DF+mIWw/b7GC1bClLO5BuhUy60nw7187a0JAG/w7j20PjhzbxbBJ42Ago8SwSWsQdk8An4ZQEY+K6QqWRABom9nQt0QiITz/zanHFCxzjh8QLSegQN8TecrA3QBesVfch7ENVlAXfw1WKWJ7NC7iMAAMO8gBtnwFzfKlYZHGMyyh9ZudV2h7u1v/EV2pN2oxo4aZDuE1HAbdxKrTd01ItZtxNIiXVIpfPkpeodgSTG61/tTb3hjY3LJXNT0axluQ9jrkkmBK4N2j4OrILWeeQwEbiAK+QWsAr4M5UkE0nvjbA6vKIYxwJRcfsoUgVgdJwz8kcXVeA6BFvQjwRKOFmXF0ESoC1g91RM5kb8UhJr5lrmZb2BvSyIPK/il7uyYChA2Burv/epiNMP36DjYPpx6MiM00QpKNikySGGpvYntnWi1XGEbBpOXI50FinTTdcjy3uqGzu2Q5l57C50bf5JWQbVUXnYAIBPmB8gn8q6DHFzIOhC3LLMFC929xiXVpmcf4LsBdxem9bI6m1+8Si1hAmXUUs82QwKWpnmUkcRAc2O4H1Cy+Jl6mg1Znx8hR4DXe2v/BqYPCGxcJ58TKGu6QP4vODZKa0rLJvIGO57HCMim6vpDPtIavMc+YqQ7ELMuwc4VgtWQHtObYxMHpTcWAEjBsTv9neWuIUCIg2wWjZLUq8kLhBOxPcWW+yn4SRlF5aymvLdXXKcxBW3xYh1CXB+z+0PYDT26c6Y7gF7sAjjiQCR5wrjUXOc4hnEv/I+98fCLC3z3XDVx4/fa6j7qXlOtVG2sXjPk/kNUhY3lQmOMx0wDNbvAg5dLx0mVgeAbr9kydHFRGpfRrs+PWf41l89+mfUfWYf7nxH6i5Hh0uU2B+BpooZdWKN7dhP6zx/WewrhN8QdJe7uqPboHTAbTtGDVg+aCs5rPf4JngprX263cxhYZmHyVskeXPTdeU548cQezoVwIX1BrW8qmraBZFTVFWC+TdVreRBkWlqTVs1HJeg6eM4J6jrJgPR6IvjqRboW7rWa0uA5cp5Kxaey9CU1esWCUwVzurcFFEu6zi/orbgTMW3c+FH472rGWYbmMoCMuyYbU2i7PVMmfSXlmRZ+1KSV6yem/5fdhuJp/0D/Zra0rJzRdy3gFiKOhzmCtG/52gbiq4oiviHD0VV9RFHgQyrNpNUTM4nSpCvMT1/Bv2yK7wdxGthWeVkhx7fq3b0iUGLMOlJhhLIcbiyxRru1SzDO4SKPGtCw2rOZvxPNi6+f7iu6Cr28NqJxB/Ys6a1VmJa4/o4H3OEdzP3I/UilJIdfqpf7/3weXuhyVC1/l5Dg3/BQ==</diagram></mxfile>
|
Before Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 18 KiB |
@ -1 +1 @@
|
||||
<mxfile host="Electron" modified="2022-03-30T03:45:51.332Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="lKLehVM0lWkircE_ePxm" version="13.4.5" type="device"><diagram id="SNS0W3kPdRRnqGH8hLX1" name="Page-1">7ZnRbpswFIafxperAGNjXwIhaztNmtZp7S0FJ6ASnFGypH362WCSEDttp5E0bUcj1RzbYM7n3+cYAAxnq89VPM++8pQVwLHSFYAj4Di2bWHxT1oeWgulXmuYVnmqGm0MV/kjU0ZLWRd5yu57DWvOizqf940JL0uW1D1bXFV82W824UX/rvN4yjTDVRIXuvU6T+ustRLH29jPWT7NujvbmLY1s7hrrJ7kPotTvtwywQjAsOK8bkuzVcgK6bzOL22/8Z7a9cAqVtYv6XBzEy3O5/FF/JNdj7j/K//2HX1y26v8jouFemA12Pqh80DFF2XK5EVsAINlltfsah4nsnYpmAtbVs8KVT3JiyLkBa+avnCC5J+w39cVv2NbNbg5ZM0dq5Os687LWs0B8TTt+Van9hB2NWpW1Wy11x322slidjI+Y3X1IJqoibieYcsNVoSVLdtCujbGaipN19faeFsUlMP/wvlYd36EAcUgoLIQQEARiBAgIQh8EI1BEAJCLkdf7DPcnVKNl3BJ3YfSd37JS7ZDSpniIp+W4jQRLmTCHkgH50ILvqqY5Wkqb2OcBZt5Yu2QRP9IrOvgKhAdQagTdIiBoHMogOSw6kljRiaJUT0JYbeT59QzgM+dboJ1PqcGnyOTzw+mmk63PdkQEIyBGJso+LYUjBSSBwIs9RMQ+YsoIB4g40ZaNvAtjdXpKccZiKLn9ihCw9p3XOXYtgEiBXQEaLP2icEQu1n7BNYtdoMGJ5KwxCivW4JcZL2CvBBBL5MXORgYqIG5vPgBIhcEAfAhiDypHMnGk/GHQgnJH0lIg7KZTBwzmxTfYvRs4jBEuLFODQ06bLhhdoqYZ/I5xR6Mj+FzZyfCn0C0MSVpngwgQg9yfRI/2MhjLCOPXLpEbNEXqncbW9CpRRbvaWA0AiR4AbD3tu1RHXBfYRDpvGyTwtyD8TIk0SqkeJKOH4EA/eeleLkGfR2ZFzXwWu9a24TNVnm4P3BS8HYwUT1ZOC4mR98lnTXHG4lMGa/yR2GLC9VgiIxuJ6VzsS4m95ixyjHtgrT96geREISnFpq6/NocmsRGKAQ+bkKTAPb+X5zu4fT6IcnR96xNpjduXpuK2BRKVLIgtGU1KcRI5hV6WvhREb5+uNI/RHz4cAXJqYUr016YyDd2tNGZEBAdK8FJ5YlkEMsN8t43RKfJcgB0uy+PPNMaCfEg7MTp5iNiU7f1KRZGfwA=</diagram></mxfile>
|
||||
<mxfile host="Electron" modified="2022-04-13T07:30:48.479Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="5B-aXL7o7yfv3TfiIJa3" version="13.4.5" type="device"><diagram id="SNS0W3kPdRRnqGH8hLX1" name="Page-1">7Vltk5s2EP41mmk/OAMIYfgItu8lbWcyvUyTbx0ZZJs5DA7mzvb9+molAcIo8V3vcJymPo8PdiWQ9tlnV9IiPFnvr0u6Wf1RJCxDjpXsEZ4ix7GxZfN/IDkoiT3GUrIs00TJWsFd+sSU0FLShzRh207DqiiyKt10hXGR5yyuOjJalsWu22xRZN23buiS9QR3Mc360k9pUq3qaXhBq7hh6XJVv9ojrtSsad1aTWW7okmx00R4hvCkLIpKXq33E5aB+WrDyH5XX9E2IytZXj2nw+fPs4ebDb2lf7FP0yL8kn74k4zUYB9p9qBmrAZbHWoTlMVDnjB4iI1wtFulFbvb0Bi0O446l62qdabUizTLJkVWlKIvXhD44/JtVRb3TNN44gOae1bFq7p7kVfKCfhs5L3WSX64fJnR7Vb1aewKHfpGUXZ6ZGXF9ppIGemaFWtWlQfeRPlo43u7FnDiKdlKw5pYSkiVky2bZ7Uw8AuFxAtQ8QyoeFkFk93QvAOP9+UBHCiKpZVCriyXc/oLHxr/8tdbxqtfkSPNZYGJRwu6TrOD7L4u8mIrAO402QpYoIG12bfv5VdL+Z8cxwHCZwxS4eLNXW0BImzAJVO4hoERmCbhhjvV1m7a1kj/q8c47WOkpRsN/5lxDEgAP1FQ30YYZARu4cefgCyEW3hZBLe+/4GV62uW141CGEIAP7Mx6OEqsrp9gnYgEthmINxlxeQkxUBsi1udTiDNi1z00vjXEdMsXeZCFHNzMaGNgBIpD3Vho1ynSSJfr/McNILpIK+jQTuWhrMgcogcnyR120gSVpuAJC0ILCHQsJBMfQ7ajaoBuqUzb64/xG09wzpoPkA0uSR8o8OWplPEbztqOrpt5UttAMd+KG4bZ9SFXYqodj0uyRDAI4qMAjXxjuK18JlOUO4GX+EU3UitRNJLGh859pDGP8xZoJsn9EhOjsP8IOG71roqKtfh3O2Hc8c3hHNnqGjuD5tjE8r8RWzMsbHP5otTOXZIMBw/6IIRGMAgBjD8ocCok7uOxsxH0RXiQ+MXoY14XOfhPhijyEM8hkc+fGcB8sfIvwJVZKPQ6mF4ebxzzsk7Z+x2oMbO9+adbRugDlAwRUEAMPLB+DYgzFENNITfdAHsxyw2knPuE5dYl0RO4pPvTU7cQ+z97Uc0c1EUoRAjvoQKJWicnBMUYEAvnAJ6bwraYuGYQUu8uUdO7loGBc26NMzIsOmN2QlhYxMYgTfG9JLAeHZ2c7zB0DBsHYEsNjAIQh3/YkGoK0h1EAV5MuvHvJ88mZFuKjOcCJw5lY2/DSvfYPrRM2D9ac5ylNbrEhSTPpC2iaDuYEAaNgMqh40BtnCGIvI/kKeAdA2MPDOQgQFIvmvguwOxuIwwCojaUIRvvDz5D+AX9Jct58XP6e8D34nPD5IKV0WZPnEZzRRI5ztgsY+w9PpcdAdKjvvr3zfYetzcPHl/lzQ93CaT+ci0zWtCKt8xTFDoiZDKN/LOS3b0rzqVIcxPXBNJfWeOT5P0BII9uAygPnvj55qOyIbaRJghNKxvfoSQ+QZgeEeh0VR+csZDlZ/MaJhyGxFbb+8Cw6OF+sfNQwBjWDwOtgsw4uL0j0dMaw4CJ5hRiGZXcEjSVqQAwhlsFXhQ9Pk606pbBBcI6mtrCK+C3sanawjYOiv0pkL9i0rC5orwN+rA/EF0vRFKjCGTrVj2yADLngZ9pVLsECgVd3RylKDMi3JNs656p2wJeleOUygzVnFvGkFZOs2Xxv7gsiPlfaCuC526OuXOlVdaFVtXViXNtwv+0PrxeVsB3xVl0n273n1O4/ulcN3Rkc0d129szRe97TXRLJ+k201GldXTPEu1Fy+yglb6gI7r7u+nv9nvvBfWBk8kzzdgkHu0SLQN1YBmIakzCL+cQUjVT1udVjnFs38A</diagram></mxfile>
|
BIN
docs/java/jvm/pictures/java内存区域/method-area-jdk1.6.png
Normal file
After Width: | Height: | Size: 160 KiB |
@ -1 +1 @@
|
||||
<mxfile host="Electron" modified="2022-03-31T03:28:42.359Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="QzftLCDC_3xCinoJ3sk4" version="13.4.5" type="device"><diagram id="2YC4MhdPOoUwFEyv9jkW" name="Page-1">7Vptb6M4EP41lm4/ZAUYA/4ICeltTyutrrc63aeTA06CSiBHaNPurz+PMe/eS6tLULrbtFKdGb8xzzzj8VCE57unm4Ltt5/zmKfIMuInhBfIskyKsfgDkudKQqlbCTZFEqtOreAu+caV0FDShyTmh17HMs/TMtn3hVGeZTwqezJWFPmx322dp/1V92zDR4K7iKVj6Z9JXG4rqWe5rfxXnmy29cqmQyvNjtWd1ZMctizOjx0RDhGeF3leVq3d05ynYLzaLtW45Xe0zcYKnpUvGfBXsDO+8psvv//tf/q8IeFiHdGZ5VTTPLL0QT2x2m35XJugyB+ymMMsJsLBcZuU/G7PItAeBehCti13qVKvkzSd52leyLF4TeBHyA9lkd/zjsaRH9Dc8zLa1sPzrFROIB6n+t4ZVH2EfPzwyh6PvCj5U0ekjHHD8x0vi2fRRXli42LHFlfiKNm2g2kjZMqXNs1crblFQ1n8NdZ3x9YPHUQdFFBoBBhRgkKCvDkKfBQuUTBHnidVBgpEw4aeHpGNAPn4Cy92NzyDMX6IaIhCF3kh9FaD6QheYa6yj2EfqyzP+ABYJWJpssnE10iAwIU8AOMngju+UuySOIZltE7TupUxAJ78T4CVdmaKmeSYGnF7jLhnahC3Lga4NwL89tMfDXqAlm8gz4SGQItiCeQCUe+8rFyvrSjSsTJ2Vg45ycozgFObXUFDPDKCxiIaaLyLQUMvGwm5GRPu6mxOHRezKWxu9W1u0TEdtDa3LhYAsaEJgML1TeADxD3xiyU9lsg3Ie4JbvjLNxDDrPNA1g9gWHNkNYyYJIBh878AO4nTj5ZKKK3TJxYmY5hMHbHsi8FkaWCqThIX0BG5QUDe8VJ42RpaTYwXflEi+I5XBQMdJwsT42WP8PooP2/kZNrmRfJNyFiqOpwjoxukdLYzZpU96VlFNKTyEKWI+pJCAaJLSbPqdiVyDUfepb6Xcl8nludIDAfQubqAiJ0psfsJ6xJ1sBtEu8bI3aTPnbROgXV1CkGjBZAJmFTdWQWBlsAbofJcaJ8VMS/i+jvryiM2MSa4P7nG6TzPMjTIuBcDZlxPkOHLgFB2/eHrTIWeEWN0uEx7TdIVE5wUzH/Ys6yHi/PPA5SAg6iyuS+UxWb1CxHPLLYn1jd6zQ/tCNHayL9tau8if458R6aKHgqkN0CjQ0pIJ01wEbUh8YDVntRk5yRtzLi31pLWiTy+Wk9AWof279AEaypNk5K2ToIGpBWZh8AOgJtLKGU0DVxVuKX+LXtkN/A2pAZuVWj9CGw4O0gjgi+Zzv6p8pWR14ilFpD8iKQIIjhplqqWETugGPnkSgNJylY8DVh0v5Hy4eKtJ5nO+MAO5I+cs2RlksPaUI0a+OMZ/A8PcitHU4Q2dcHJvJj/6Wo473mx7sCvX9BcTV5sawo7P1jAtup3VNdTprY15Znecd6ew4I5ga/IA+HcgcINvH4TFFpA3a1b3qYhkG2Cc/iKrzsYn06qpy3u2OPiTiexao5lIs9KAipqI//Mb+jeDmC6Os/EgI0LPT99NQ57A5Q0VYRJq3G2pobwyiuR0VyDOq0PSB08hkx812yXpM/VGDER2+2lEmMbDM3TRw6ojTT9Sdrs2SIie+7rql2CMsuLHUv76qOyJejtap9SmfJS+M1MPGqUZBvteHDOmfIzUCtX66kT4UaZmt7obE0qy4Jlh7WYtJ5eeG7d4ZgXcX/17vBVk0bPBja3bK+xtWXTtk06lo+Twz5lyupJliadhddpzsruhob3kNvFb+ZH96WnoGLwiWh6BgLZAwKZWJf7aRiEX88g8bX9PzCp6/w3HQ7/BQ==</diagram></mxfile>
|
||||
<mxfile host="Electron" modified="2022-04-13T07:31:40.068Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="1agHgKCaMXpfD4rIeFVS" version="13.4.5" type="device"><diagram id="2YC4MhdPOoUwFEyv9jkW" name="Page-1">7Zlbb6M4FIB/jaWdh4wAYzCPkNLMzGqkarur3e5L5YC5qARngTTp/Po9BpOE4Nm0Uoimms2MFOccfOF852K7CM9Xu0XF1tlXEfMCWUa8Q/gGWZaJDRO+pORFSUwXd5K0ymMlOwju829cCQ0l3eQxrwcPNkIUTb4eCiNRljxqBjJWVWI7fCwRxXDWNUv5SHAfsWIs/TOPm6yTUss9yD/xPM36mU3H6zQr1j+s3qTOWCy2RyIcIjyvhGi61mo354W0Xm+Xrt/td7T7hVW8bF7T4SFYGX/wxd1vj/7nrykJb5LIm2GnG+aZFRv1xmq1zUtvgkpsypjLUUyEg22WN/x+zSKp3QJ1kGXNqlDqJC+KuShE1fbFCZH/QF43lXjiRxqn/UjNE2+irO8uykY5AbxO9/uoU/cB+fjllT2eedXw3ZFIGWPBxYo31Qs8orSOo8Ao19yD2h44W66SZUeMbU8JmfKtdD/2wfzQUATeQsMd0wg95N0gz0Ohg6iBqIlCgugt8qhUUVe2L0qMRjyKdMSWlNjEOEfsAmRcY0gGEw0ZQ0PGnQwM1YAhyAcezsj68JbN0MRDU5ai5Cd2VyJW5GkJPyOwHQd5IG2WQzLylWKVx7GcRsv0QN044UImihgdF6rhYk3GxdOkL6eQ5q/XrBxwcf7ZyFQbRJ3NfVBW6fIXAu8My4P5jUHzw6EHtNL2WyKHWHRR6CJ/jnwHhTYKKApab5CNo6CEeA1M6SJqQfCC3ZrUYJcM2phwGtu6oKXWEp9Ps5dwDo8MnINgcr2g/bt+fIwfPrl/Pd1tHiL/ecEbMTM1vvEOSltasLruE0e/ZzhAGhHRcPsuJPN8ySOOhhExpoJkTQspZpwm2mrmRJQvk3OQpoRhed6wzBmadEo0NOhUMLCmykFSg82GIRu+iehc5jXIgIHznynvhyuJp3CtU/KTkqb2kDS+YuHUkiYj0l8+/95WswD5uK1v3V4TSM+Rh/vSRy+bQpPE0u81Y2fpkLMpdEpmeJgqiacpZ1cNzolPatyETYSrY+E5LmY/EotXJ0rLmQqG7qDmyuQXtLtECv9xG063MmvKoxvkxfFB7SfPi+Zwy4h1J/CrpkXdMe8IqxciGrwC68+2rXRP4tMZczR18WlPxVFzLDyc3Rzkhygg/3M8x9HWxON1OfbnlQFI2H/CPrO9EAswgrrcbU39C+9N3j8/Yoz3LFfmNz6Df2w/76QSZqLKv4GMFQrS9UqjdRKL7jgW7WuWRnN8ZNCFIpFHxMBH4a08OFB6x6vVgpdt+g1lAYV6SiH9Gv0T3jtwBXJV8vaQvO6WFesu0qZDrzt6dJeaMAEDTZSxqubdOvpb002TyP3U6BL1jfez6kK2//rQDmFIOrOErfLipXs048Uzl6yP9HWLT2otst4dK7pJpaYU1UpG9163VRaVStvomBoFb8ChZrDmKC/TcU/psjPlfVK3d8Bel4NnlWpUo19Lq2kqVtYJjNWP2nqyxC2qeDjjvuOSRU9p666zE2tZNu0MZdmeapDeZnFerwum7JWXRd7PlBSCNSfTn2L7cvOr+dF97V22CuEzFfcCwWKfpElTt2UxNcGC3x4s8PPw19pWd/RHbxz+Cw==</diagram></mxfile>
|
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 139 KiB |
@ -1 +1 @@
|
||||
<mxfile host="Electron" modified="2022-03-31T02:52:11.928Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="A-nn-0EuAYjRZmWQjJ5A" version="13.4.5" type="device"><diagram id="gYNeldG73rc2GvLzjtzR" name="Page-1">7Vptc5s4EP41mrl+cAcQEugjODjX3PRTbuZu7psMsk2DwcUkTvrrbyXEu3pppzbjXOtkJvKu3thnd/VoCcLL/fNtyQ+7j0UiMuRYyTPCN8hxbIYx/JGSl1rCmFcLtmWa6E6d4D79IrTQ0tLHNBHHQceqKLIqPQyFcZHnIq4GMl6WxWnYbVNkw1UPfCsmgvuYZ1PpX2lS7Wqp73id/HeRbnfNyjZltWbPm876SY47nhSnnghHCC/Loqjq1v55KTJpvMYu9bjVV7TtxkqRV98yoPqc/v3PMd++ZB8se7N+uv/0abXQszzx7FE/sN5s9dJYoCwe80TISWyEw9MurcT9gcdSewLMQbar9plWb9IsWxZZUaqxeEPkD8iPVVk8iJ6Gqo/UPIgq3jXDi7zSPgBPU3/vDao/IJ8+e/MgoqzEc0+kbXErir2oyhfooh2x9bBTByuhWrbrQdoKuXalbTtXZ21oaIN/h/GdqfEjihhFIZONECNGUESQv0RhgKIVCpfI91HkoYApCUMQTaH7UVS8hgQ6BxFikezjRyi0mlFsAiuYqRpiN8QoL3IxAlSLeJZuc/gag/EFyENp9BRCJtCKfZokchmjs3TuZI0AJz8IrNYubJhJjWmQdqdI+7YBaedSQJMJ0Hcf/kSRi8IQBVgBaiHflg0Ai2GF4w1i/nmDcbNx4tgUjAldU/JqMJ4Bm8bqGhnikwkyDjEg418KGXrZ/CfshAjPZHJGPcznMLkzNLnDpsFgNLlzsbTnGdIeOL4to0FmO/jFKjhWKLBlIoTICFZvIIE550FsmL2w4Zxq42GW7OX/F16vwvR/ow9aS4dhhckUJdsUVu6lUGIGlOpTxJPgAC0IyS+4NFyuIajmhavZwCvk7xdeNQxsShRmxmt6U3qvPm/kXNoVZfoFZDzTHc7B5kZ0zqXTqHLnPKnsKdFWQbVEwVJmQ2jIKxEQDCppxldZ9nVCeA4yOELMM+VBTOeE7MIM/Jpz3CjJtUbuMz1v1oqEbeLmDDGIEnUq+fU1FQJoJeMGVL4n22dFzI+F+Zq69olLrBnuTJ71OrtzLAMy3sWAMZFwosoG9A2krzOVdiYRY8Jl1ruRbaDdDs2k+Y8Hng9woZ8fZa03jGubB6Ast+vfCDwzbA/WtwbNd90IaG3V347Re/JIC6hiiD4KlTfIRi8oJYu0pYvoDcED1nvSk50zaBMu/I0xaGnsi/VmhqClbHhxJthQXJo1aB0Tx1cFDklHXFXr83Q2DT1dqmXBHX/it/K1RwPcujT6kbTh4qiMKH3Jpofn2lcmXgNL3UjyE/kqg5N2qXoZyYwwCsiVJpKMr0UW8vhhq+TjxTtPsun0wA7Vj5qz4lVayLUXeHKInMH/8IhbUUPZ2TYlJ/ti/md4uwMuAEc5C9RpHiK20gRZvk74eXmx17zPuxpeTJ3L8uIrSNhO81bqikrTJqv3j/PuHIbICYPe7ZLKeo28XUII3chyW7+mzSIZbDOcw1d83cH42kqmnmvIjy2xao9los5KIlXMRcGZX8q9HcBM5Z2ZAZvWd376Ihz2RygZqgizFuG8H78SWe01qNd6h/TBYyniu+H7NHupx8BEfH9QSoxdaWiRPQmJ2kQznKRjzw4B9jzU1buUyrwo9zwbqk/allLv1vtUykxU4DcLeNQ4zbfG8dI5F9rPpFq72kCdghvlenqrtzWlrEqeHzcwaTM9eG7T4VSUyXD1/vB1S6MXI5s7rt/a2nFZ1yY9yyfp8ZBxbfU0z9Lewpus4FV/Q+N7yN3NH/Z7/1tPQR3Br2TTMwSQOwogG5u4nyGC8PdHEHzt/uFL6Xr/NoejfwE=</diagram></mxfile>
|
||||
<mxfile host="Electron" modified="2022-04-13T07:43:21.271Z" agent="5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.4.5 Chrome/83.0.4103.122 Electron/9.1.0 Safari/537.36" etag="MJnw9VmKbU_C3nY3pDWl" version="13.4.5" type="device"><diagram id="gYNeldG73rc2GvLzjtzR" name="Page-1">7Zlbc6M2FIB/jWa6D94BhEA8gkO2TZu+pDud6UtHBnFpZKCYxM7++h6BsLmodTJjvJvZOpmxOAcJ6XznImSE19vDp5pV2X0Zc4EsIz4gfIMsyzQNB76k5KWTeJ7bCdI6j9VNJ8FD/oUroaGkT3nMd6Mbm7IUTV6NhVFZFDxqRjJW1+V+fFtSivFTK5bymeAhYmIu/T2Pm6yTUss9yX/keZr1TzYdr9NsWX+zWskuY3G5H4hwiPC6Lsuma20Pay6k8Xq7dP1u/0V7nFjNi+Y1HaLMu/ul+ny4qf58uad/ZH/9WpkrU832mYkntWI12+alN0FdPhUxl6OYCAf7LG/4Q8Uiqd0DdJBlzVYodZILsS5FWbd9cULkH8h3TV0+8oHGaT9S88ibKOu7l0WjnACW010POnUfkM8Xr+zxzOuGHwYiZYxPvNzypn6BW5TWcRQY5ZlHUPsTZ8tVsmzA2PaUkCnfSo9jn8wPDUXgDTT6GQxphB7ybpDnodBB1EDURCFB9BZ5VKqoK9sXJUYjHkU6YhtKbGKcI3YBMq4xJoOJhoyhIeMuBsbUgCHIBx7OzPqwymZs4rEpi7LgE7srERN5WsBlBLbjIA+kzXJIRr5SbPM4lo/RMj1RNyZcyEIRo+NCNVysxbhYmvTlCGn+XcWKERfn7yeZaoOos7kPyjrd/EBgzTA9eL4xan449YBW2n5L5BCLLgpd5K+R76DQRgFFQesNsjEISojXwJQuoiYEC+zmpAa7ZNDGhNPY1gUttTb4fJq9hHN4ZOQcBJOvHbT4fda2VLDdrs8c/abhQpTM8zWPOBpIxFiMkr0spZhxmmjrmRNRvknOUVqSBuyGx4XO0CRUosFBF6NBNIUO8hrsNwzZ8E1E1zK1QRIMnP/Met9cVZzStaboF0VN7TFq/NVrpzNDfffTb21FC5CP2xrX7TcB9Rp5uC9/9LJZNEks/X4zdjYOOZtFl4SGx9mSeJqSdt3wdJdNltyEnYSrg+E5LmbfEoxX50rLWYwG1SRLV+a/oN0rUvjHbUDdysQpX+AgNc5f177z1GiON45Y9x5+3cyoORQZcvVCRINXcP3eNpfuJEKdOUhTF6H2UiD7lDF9be/e4Rzkhygg/4M8B9LWROSVQerOX2ATCpvN9mAswAhqc7c/9S+8P3n//Igx37dcmd/8nOZj+3kntTAr6/wLyJhQkK5XHK1JLLrzWLSvWRyx5lRFE4pEvicGPgpv5csDpfe8YZ3JZQIOZQ2FkkohARv9Pd47cAZyVfb2mL3uvBVfF77usOZt563G8Yx10PqA1DGkIY29Stg2Fy9dHxiIbatWibE84sy4eOaS5UwzHmTXIpNDWKQ6THTdLKWyKOstE2P1XtlS6u1unq1S8Aa8aQVLjfIi1faXLrtS3ifVygFH6hycq1DDG4OptcqmZsUugUH74cGf+xv2ZR2Pnz7svmHRY9q67mpic8umR1tbtndqk4Hl43xXCaasnhciHzw4ESVrhhOaHo3f3fxsfqSvPepWcX2mEF8gguxJ9jR1OxlTE0H47REEl6cfc1vd4CdxHP4D</diagram></mxfile>
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 86 KiB |