JVM基础面试题及原理讲解

  • 时间:
  • 浏览:0

/**

    return new Integer(i);

4

JDK1.4中新加入的 NIO(New Input/Output) 类,引入了两种 基于通道(Channel) 与缓存区(Buffer) 的 I/O 法律法律法律依据,它都可不都可以直接使用Native函数库直接分配堆外内存,要是 通过有六个 存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引用进行操作。原先就能在或多或少场景中显著提高性能,由于解决了在 Java 堆和 Native 堆之间来回基因重组数据。

实例数据帕累托图是对象真正存储的有效信息,也是在进程运行中所定义的各种类型的字段内容。

String str1 = "abcd";

Integer i4 = new Integer(40);

Double i4 = 1.2;

哪几种组成帕累托图或多或少是进程运行私有的,或多或少的则是进程运行共享的。

相对而言,垃圾收集行为在这一 区域是比较少出现的,但两种 数据进入法律法律法律依据区后就“永久趋于稳定”了。

5

从上面的介绍中亲戚亲戚让我们歌词 歌词 都知道进程运行计数器主要有有六个 作用:

}

3

2

System.out.println("i1=i2   " + (i1 == i2));

另外,为了进程运行切换都可不都可以恢复到正确的执行位置,每条进程运行都前要有有六个 独立的进程运行计数器,各进程运行之间计数器互不影响,独立存储,亲戚亲戚让我们歌词 歌词 都称累似 内存区域为“进程运行私有”的内存。

3

1

3

在创建对象的后后 有有六个 有点儿要的问题图片,要是 进程运行安全,由于在实际开发过程中,创建对象是很频繁的事情,作为虚拟机来说,前要要保证进程运行是安全的,通常来讲,虚拟机采用两种 法律法律法律依据来保证进程运行安全:

1

3

System.out.println("40=i5+i6   " + (40 == i5 + i6));

6

局部变量表主要存放了编译器可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不同于对象两种 ,由于是有六个 指向对象起始地址的引用指针,也由于是指向有六个 代表对象的句柄或或多或少与此对象相关的位置)。

2

应用场景:

String str2 = new String("abcd");

推荐阅读:Java 中几种常量池的区分

System.out.println(str4 == str5);

本机直接内存的分配不必收到 Java 堆的限制,要是 ,既然是内存就会受到本机总内存大小以及解决器寻址空间的限制。

5

在 JDK 1.8中移除整个永久代,取而代之的是有六个 叫元空间(Metaspace)的区域(永久代使用的是JVM的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制)。

1

HotSpot 虚拟机中法律法律法律依据区也常被称为 “永久代”,本质上两者两种 等价。仅仅由于 HotSpot 虚拟机设计团队用永久代来实现法律法律法律依据区而已,原先 HotSpot 虚拟机的垃圾收集器就都可不都可以像管理 Java 堆一样管理这帕累托图内存了。要是 这并总要有六个 好主意,由于原先更容易遇到内存溢出问题图片。

Java 虚拟机在执行 Java 进程运行的过程中会把它管理的内存划分成若干个不同的数据区域。

4. 设置对象头: 初始化零值完成后后 ,虚拟机要对对象进行必要的设置,累似 这一 对象是那个类的实例、咋样都可不都可以找到类的元数据信息、对象的哈希吗、对象的 GC 分代年龄等信息。 哪几种信息存倒进对象头中。 另外,根据虚拟机当前运行请况的不同,如与否启用偏向锁等,对象头会有不同的设置法律法律法律依据。

6

5

对于 Java 进程运行员来说,在虚拟机自动内存管理机制下,不再前要像C/C++进程运行开发进程运行员原先为内有六个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题图片。正由于 Java 进程运行员把内存控制权利交给 Java 虚拟机,一旦出现内存泄漏和溢出方面的问题图片,由于不了解虚拟机是咋样使用内存的,越来越排查错误由于是有六个 非常艰巨的任务。

7

i4=i5+i6   true

System.out.println(str3 == str5);

直接内存并总要虚拟机运行时数据区的一帕累托图,也总要虚拟机规范中定义的内存区域,要是 这帕累托图内存也被频繁地使用。要是 也由于由于OutOfMemoryError异常出现。

1

    if (i >= IntegerCache.low && i <= IntegerCache.high)

Double i3 = 1.2;

String str1 = "str";

40=i5+i6   true

本文从 JVM 行态入手,介绍了 Java 内存管理、对象创建、常量池等基础知识,对面试中 JVM 相关的基础题目进行了讲解。

7

12

System.out.println("i4=i5   " + (i4 == i5));

Integer 比较(==)更宽裕的有六个 例子:

2. 直接指针: 由于使用直接指针访问,越来越 Java 堆对象的布局中就前要考虑咋样放置访问类型数据的相关信息,而 reference 中存储的直接要是 对象的地址。

3

本地法律法律法律依据被执行的后后 ,在本地法律法律法律依据栈也会创建有六个 栈帧,用于存放该本地法律法律法律依据的局部变量表、操作数栈、动态链接、出口信息。

1

public static Integer valueOf(int i) {

对齐填充帕累托图总要必然趋于稳定的,也越来越哪几种有点儿的含义,仅仅起占位作用。 由于 Hotspot 虚拟机的自动内存管理系统要求对象起始地址前要是 8字节的整数倍,换句话说要是 对象的大小前要是 8字节的整数倍。而对象头帕累托图正好是8字节的倍数(1倍或2倍),要是 ,当对象实例数据帕累托图越来越对齐时,就前要通过对齐填充来补全。

通过上面的介绍亲戚亲戚让我们歌词 歌词 与否花费知道了虚拟机的内存请况,下面亲戚亲戚让我们歌词 歌词 都来删剪的了解一下 HotSpot 虚拟机在 Java 堆中对象分配、布局和访问的全过程。

 */

i1=i2   true

String s1 = new String("abc");

法律法律法律依据区与 Java 堆一样,是各个进程运行共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。随便说说Java虚拟机规范把法律法律法律依据区描述为堆的有六个 逻辑帕累托图,要是 它却有有六个 别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。

8

先有字符串 “abc” 倒进常量池,要是 new 了一份字符串 “abc” 倒进 Java 堆(字符串常量 “abc” 在编译期要由于选取倒进常量池,而 Java 堆上的 “abc” 是在运行期初始化阶段才选取),要是 Java 栈的 str1 指向 Java 堆上的 “abc”。

7

3

进程运行私有的:

System.out.println(i11 == i22);

Java 堆是垃圾收集器管理的主要区域,要是 也被称作GC堆(Garbage Collected Heap).从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,要是 Java堆还都可不都可以细分为:新生代和老年代:再细致或多或少有:Eden空间、From Survivor、To Survivor空间等。进一步划分的目的是更好地回收内存,由于放慢地分配内存。

9

System.out.println("i4=i5+i6   " + (i4 == i5 + i6));  

System.out.println(s2);

Hotspot虚拟机的对象头包括两帕累托图信息,第一帕累托图用于存储对象自身的自身运行时数据(哈希码、GC分代年龄、锁请况标志等等),另一帕累托图是类型指针,即对象指向它的类元数据的指针,虚拟机通过这一 指针来选取这一 对象是那个类的实例。

5

2

创建了有六个 对象。

4

1

5

System.out.println(str1==str2);

i1=i2+i3   true

Integer i11 = 333;

1 String 对象的两种 创建法律法律法律依据

String s1 = new String("abc");

9

Java 虚拟机栈会出现两种 异常:StackOverFlowError 和 OutOfMemoryError。

进程运行共享的:

2

System.out.println(i1 == i2);

5

1. 类加载检查: 虚拟机遇到十根 new 指令时,首先将去检查这一 指令的参数与否能在常量池中定位到这一 类的符号引用,要是 检查这一 符号引用代表的类与否已被加载过、解析和初始化过。由于越来越,那前要先执行相应的类加载过程。

进程运行计数器是一块较小的内存空间,都可不都可以看作是当前进程运行所执行的字节码的行号指示器。字节码解释器工作时通过改变这一 计数器的值来选取下十根前要执行的字节码指令,分支、循环、跳转、异常解决、进程运行恢复等功能都前要依赖这一 计数器来完。

推荐阅读:Java8内存模型——永久代(PermGen)和元空间(Metaspace)

String s2 = "abc";

11

一段话 i4 == i5 + i6,由于 + 这一 操作符不适用于 Integer 对象,首先 i5 和 i6 进行自动拆箱操作,进行数值相加,即 i4 == 40。要是 Integer对象无法与数值进行直接比较,要是 i4自动拆箱转为int值40,最终这条一段话转为40 == 40进行数值比较。

13

这两种 对象访问法律法律法律依据各有优势。使用句柄来访问的最大好处是 reference 中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而 reference 两种 不前要修改。使用直接指针访问法律法律法律依据最大的好处要是 下行传输速率 快,它节省了一次指针定位的时间开销。

3

4

尽量解决多个字符串拼接,由于原先会重新创建对象。由于前要改变字符串一段话,都可不都可以使用 StringBuilder 由于 StringBuffer。

选取以上两种 法律法律法律依据中的哪两种 ,取决于 Java 堆内存与否规整。而 Java 堆内存与否规整,取决于 GC 收集器的算法是”标记-清除”,还是”标记-收集”(也称作”标记-压缩”),值得注意的是,基因重组算法内存也是规整的。

在 Hotspot 虚拟机中,对象在内存中的布局都可不都可以分为3块区域:对象头、实例数据和对齐填充。

System.out.println(s1 == s2);

System.out.println(i1==i2);

6

2. 分配内存: 在类加载检查通后后 ,接下来虚拟机将为新生对象分配内存。对象所需的内存大小在类加载完成后便可选取,为对象分配空间的任务等同于把一块选取大小的内存从 Java 堆中划分出来。分配法律法律法律依据有 “指针碰撞” 和 “空闲列表” 两种 ,选取那种分配法律法律法律依据由 Java 堆与否规整决定,而Java堆与否规整又由所采用的垃圾收集器与否中含压缩收集功能决定。

        return IntegerCache.cache[i + (-IntegerCache.low)];

通过直接指针访问对象

1

2

5. 执行 init 法律法律法律依据: 在上面工作都完成后后 ,从虚拟机的视角来看,有六个 新的对象由于产生了,但从 Java 进程运行的视角来看,对象创建才始于英文英文,<init> 法律法律法律依据还越来越执行,所有的字段都还为零。要是 一般来说,执行 new 指令后后 会接着执行 <init> 法律法律法律依据,把对象按照进程运行员的意愿进行初始化,原先有六个 真正可用的对象才算删剪产生出来。

String str5 = "string";

3 String 字符串拼接

i4=i5   false

4

System.out.println(s1 == s2);

记住:我希望使用 new 法律法律法律依据,便前要创建新的对象。

内存分配的两种 法律法律法律依据:(补充内容,前要掌握)

3. 初始化零值: 内存分配完成后,虚拟机前要将分配到的内存空间都初始化为零值(不包括对象头),这一 步操作保证了对象的实例字段在 Java 代码中都可不都可以不赋初始值就直接使用,进程运行能访问到哪几种字段的数据类型所对应的零值。

System.out.println(str3 == str4);

String str3 = "str" + "ing";

解释:

6

System.out.println(s3 == s2);

Integer 缓存源代码:

3

8

4

建立对象要是 为了使用对象,亲戚亲戚让我们歌词 歌词 都的Java进程运行通过栈上的 reference 数据来操作堆上的具体对象。对象的访问法律法律法律依据有虚拟机实现而定,目前主流的访问法律法律法律依据有使用句柄和直接指针两种 :

通过句柄访问对象

结果:

String s2 = s1.intern();

String str4 = str1 + str2;

1. 句柄: 由于使用句柄一段话,越来越 Java 堆中由于划分出一块内存来作为句柄池,reference 中存储的要是 对象的句柄地址,而句柄中中含了对象实例数据与类型数据各自 的具体地址信息。

验证:

Java创建对象过程

2 String 类型的常量池比较特殊。它的主要使用法律法律法律依据有两种 :

1

Java 虚拟机栈也是进程运行私有的,每个进程运行总要各自 的Java虚拟机栈,要是 随着进程运行的创建而创建,随着进程运行的死亡而死亡。

System.out.println("i1=i4   " + (i1 == i4));

Integer i1 = 33;

和虚拟机栈所发挥的作用非常累似 ,区别是: 虚拟机栈为虚拟机执行 Java 法律法律法律依据 (也要是 字节码)服务,而本地法律法律法律依据栈则为虚拟机使用到的 Native 法律法律法律依据服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。

4

System.out.println(s1.equals(s2));

2

9

String str2 = "ing";

6

i1=i4   false

法律法律法律依据执行完毕后相应的栈帧也会出栈并释放内存空间,也会出现 StackOverFlowError 和 OutOfMemoryError 两种 异常。

与进程运行计数器一样,Java虚拟机栈也是进程运行私有的,它的生命周期和进程运行相同,描述的是 Java 法律法律法律依据执行的内存模型。

Java 虚拟机所管理的内存中最大的一块,Java 堆是所有进程运行共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的要是 存放对象实例,几乎所有的对象实例以及数组总要这里分配内存。

结果:

既然运行时常量池时法律法律法律依据区的一帕累托图,自然受到法律法律法律依据区内存的限制,当常量池无法再申请到内存总要抛出 OutOfMemoryError 异常。

1

3

Integer i1 = 40;

4

7

8

6

Integer i5 = new Integer(40);

解释:

JDK1.7及后后 版本的 JVM 由于将运行时常量池从法律法律法律依据区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。

运行时常量池是法律法律法律依据区的一帕累托图。Class 文件中除了有类的版本、字段、法律法律法律依据、接口等描述信息外,还有常量池信息(用于存放编译期生成的各种字面量和符号引用)

2

Integer i22 = 333;

Integer i6 = new Integer(0);

Integer i2 = new Integer(40);

注意:进程运行计数器是唯不必出现 OutOfMemoryError 的内存区域,它的生命周期随着进程运行的创建而创建,随着进程运行的始于英文英文而死亡。

这两种 不同的创建法律法律法律依据是有差别的,第两种 法律法律法律依据是在常量池中拿对象,第二种法律法律法律依据是直接在堆内存空间创建有六个 新的对象。

10

内存分配并发问题图片(补充内容,前要掌握)

Integer i3 = 0;

Integer i2 = 33;

Java 内存都可不都可以粗糙的区分为堆内存(Heap)和栈内存(Stack)其中栈要是 现在说的虚拟机栈,由于说是虚拟机栈中局部变量表帕累托图。 (实际上,Java虚拟机栈是由有六个 个栈帧组成,而每个栈帧中都拥有局部变量表、操作数栈、动态链接、法律法律法律依据出口信息)

System.out.println("i1=i2+i3   " + (i1 == i2 + i3));

8

String s1 = new String("计算机");

2

String s3 = "计算机";

Integer i2 = 40;

System.out.println(i3 == i4);

下图便是 Java 对象的创建过程,我建议最好是能默写出来,要是 要掌握每一步在做哪几种。

 *此法律法律法律依据将始终缓存-128到127(包括端点)范围内的值,并都可不都可以缓存此范围之外的或多或少值。

2

Integer i1 = 40;

1