JVM学习,2024年最新进大厂面试难不难

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 是线程私有的(每个线程都有自己的程序计数器)

  • 不会存在内存溢出

2)图解

在这里插入图片描述

2、虚拟机栈


1)定义

  • 每个线程运行需要的内存空间,称为虚拟机栈

  • 每个栈由多个栈帧组成,对应着每次调用方法时所占用的内存

  • 每个线程只能有一个活动栈帧,对应着当前正在执行的方法

2)图示:

在这里插入图片描述

3)问题辨析

  • 垃圾回收是否涉及栈内存?

不需要。因为虚拟机栈中是由一个个栈帧组成的,在方法执行完毕后,对应的栈帧就会被弹出栈。所以无需通过垃圾回收机制去回收内存。

  • 栈内存的分配越大越好吗?

不是。因为物理内存是一定的,栈内存越大,可以支持更多的递归调用,但是可执行的线程数就会越少。

  • 方法内的局部变量是否是线程安全的?

如果方法内局部变量没有逃离方法的作用范围,则是线程安全的

如果局部变量引用了对象,并逃离了方法的作用范围,则需要考虑线程安全问题

4)内存溢出

Java.lang.stackOverflowError 栈内存溢出

发生原因

  • 虚拟机栈中,栈帧过多(无限递归)

  • 每个栈帧所占用过大

5)线程运行诊断

案例一、CPU占用过高

  • Linux环境下运行某些程序的时候,可能导致CPU的占用过高,这时需要定位占用CPU过高的线程

- 用top定位哪个进程对cpu的占用过高

- ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)

- jstack 进程id

  • jstack 进程id 通过查看进程中的线程的nid,刚才通过ps命令看到的tid来对比定位,注意jstack查找出的线程id是16进制的,需要转换

案例二、程序运行很长时间没有结果

可能发生了死锁

3、本地方法栈


一些带有native关键字的方法就是需要JAVA去调用本地的C或者C++方法,因为JAVA有时候没法直接和操作系统底层交互,所以需要用到本地方法

4、堆


1)定义

Heap 堆

  • 通过 new 关键字,创建对象都会使用堆内存

特点

  • 是线程共享的,堆中对象都需要考虑线程安全的问题

  • 有垃圾回收机制

2)堆内存溢出

java.lang.OutofMemoryError :java heap space. 堆内存溢出

3)堆内存诊断

  • jps 工具

查看当前系统中有哪些 java 进程

  • jmap 工具

查看堆内存占用情况 jmap - heap 进程id

  • jconsole 工具

图形界面的,多功能的监测工具,可以连续监测

jconsole 工具图示:

在这里插入图片描述

4)案例

  • 垃圾回收后,内存占用仍然很高

我们可以使用jvirsalvm命令调用出来的工具来分析

图示

在这里插入图片描述

5、方法区


5.1)定义

Java虚拟机有一个在所有Java虚拟机线程之间共享的方法区域。方法区域类似于用于传统语言的编译代码的存储区域,或者类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化以及接口初始化中使用的特殊方法。

方法区域是在虚拟机启动时创建的。尽管方法区域在逻辑上是堆的一部分,但简单的实现可能选择不垃圾收集或压缩它。此规范不强制指定方法区域的位置或用于管理已编译代码的策略。方法区域可以具有固定的大小,或者可以根据计算的需要进行扩展,并且如果不需要更大的方法区域,则可以收缩。方法区域的内存不需要是连续的。

5.2)组成

Hotspot 虚拟机 jdk1.6 1.7 1.8 内存结构图

在这里插入图片描述

5.3)方法区内存溢出

  • 1.8 之前会导致永久代内存溢出

演示元空间内存溢出 java.lang.OutOfMemoryError: PermGen space

使用 -XX:MaxPermSize=8m 指定永久代内存大小

  • 1.8 之后会导致元空间内存溢出

演示元空间内存溢出 java.lang.OutOfMemoryError: Metaspace

使用 -XX:MaxMetaspaceSize=8m 指定元空间大小

5.4)运行时常量池

二进制字节码包含(类的基本信息,常量池,类方法定义,包含了虚拟机的指令)

首先看看常量池是什么,编译如下代码:

public class Test {

public static void main(String[] args) {

System.out.println(“Hello World!”);

}

}

然后使用 javap -v Test.class 命令反编译查看结果。

在这里插入图片描述

每条指令都会对应常量池表中一个地址,常量池表中的地址可能对应着一个类名、方法名、参数类型等信息。

在这里插入图片描述常量池:

就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量信息

运行时常量池:

常量池是 *.class 文件中的,当该类被加载以后,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

5.5)StringTable

5.6)StringTable特性

  • 常量池中的字符串仅是符号,只有在被用到时才会转化为对象

  • 利用串池的机制,来避免重复创建字符串对象

  • 字符串变量拼接的原理是StringBuilder

  • 字符串常量拼接的原理是编译器优化

  • 可以使用intern方法,主动将串池中还没有的字符串对象放入串池中

以下代码信息包含:

  • 常量池与串池的关系

  • 字符串变量拼接底层实现原理

  • 编译期优化

public class Demo01 {

//1、当程序运行时候常量池中的信息都会被加载到运行时常量池中,这时a b ab 都还是符号,还没有变为java字符串对象

//2、当程序运行到了String s1 = “a”;这一行时jvm就会把a 符号变为"a"字符串对象

//3、再将"a"字符串对象放到stringTable[“a”,“b”](串池)中,stringTable是hashTable结构的不能扩容,且不能重复

//4、下一次再有引用字符串a时候就直接去stringTable中找,找不到才会创建字符串对象

public static void main(String[] args) {

String s1 = “a”;

String s2 = “b”;

String s3 = “ab”;

//相当于new StringBuilder().append(“a”).append(“b”).toString()也相当于new String(“ab”)

//但是这种new是在堆内存中它和方法区中的常量池中的"ab"地址不同,也不会去常量池中寻找

String s4 = s1 + s2;

System.out.println(s3==s4); //false

//这一种的s5是在编译期间已经确定为"ab"了所以,这行代码会在常量池中寻找"ab"

String s5 = “a” + “b”;

System.out.println(s3==s5);//true

}

}

5.7) intern方法 1.8

调用字符串对象的 intern 方法,会将该字符串对象尝试放入到串池中

  • 如果串池中没有该字符串对象,则放入成功

  • 如果有该字符串对象,则放入失败

  • 无论放入是否成功,都会返回串池中的字符串对象

注意

  • jdk1.8此时如果调用 intern 方法成功,堆内存与串池中的字符串对象是同一个对象;如果失败,则不是同一个对象

  • jdk1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,

放入串池, 会把串池中的对象返回

例1:

public class Demo02 {

public static void main(String[] args) {

//此时串池中有了[“a”,“b”]

//堆空间中有了new String(“ab”)对象

String s = new String(“a”) + new String(“b”);

//将字符串new String(“ab”)对象尝试放入到串池中,如果串池有就不会放入,没有就会放入;返回串池中的对象

//此时串池中[“a”,“b”,“ab”]

String s1 = s.intern();

String s2 = “ab”;

System.out.println(s == s1);//true

System.out.println(s2 == s);//true

}

}

例2:

public class Demo02 {

public static void main(String[] args) {

String s2 = “ab”;

//此时串池中有了[“a”,“b”,“ab”]

//堆空间中有了new String(“ab”)对象

String s = new String(“a”) + new String(“b”);

//将字符串new String(“ab”)对象尝试放入到串池中,如果串池有就不会放入,没有就会放入;返回串池中的对象

//此时串池中[“a”,“b”,“ab”]

String s1 = s.intern();

System.out.println(s == s1);//false

System.out.println(s2 == s);//false

}

}

5.8) 面试题

/**

  • 演示字符串相关面试题

*/

public class Demo1_21 {

public static void main(String[] args) {

String s1 = “a”;

String s2 = “b”;

String s3 = “a” + “b”; // ab

String s4 = s1 + s2; // new String(“ab”)

String s5 = “ab”;

String s6 = s4.intern();

// 问

System.out.println(s3 == s4); // false

System.out.println(s3 == s5); // true

System.out.println(s3 == s6); // true

String x2 = new String(“c”) + new String(“d”); // new String(“cd”)

x2.intern();

String x1 = “cd”;

// 问,如果调换了【最后两行代码】的位置呢,如果是jdk1.6呢

System.out.println(x1 == x2);

}

}

5.9)StringTable 的位置

jdk1.6 StringTable 位置是在永久代中,1.8 StringTable 位置是在堆中。

图示

在这里插入图片描述

5.10)StringTable 垃圾回收

-Xmx10m 指定堆内存大小

-XX:+PrintStringTableStatistics 打印字符串常量池信息

-XX:+PrintGCDetails

-verbose:gc 打印 gc 的次数,耗费时间等信息

/**

  • 演示 StringTable 垃圾回收

  • -Xmx10m -XX:+PrintStringTableStatistics -XX:+PrintGCDetails -verbose:gc

*/

public class Code_05_StringTableTest {

public static void main(String[] args) {

int i = 0;

try {

for(int j = 0; j < 10000; j++) { // j = 100, j = 10000

//将堆中对象放入到串池中,串池里的值是唯一的

String.valueOf(j).intern();

i++;

}

}catch (Exception e) {

e.printStackTrace();

}finally {

System.out.println(i);

}

}

文末

我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档

  • 第一个要分享给大家的就是算法和数据结构

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 第二个就是数据库的高频知识点与性能优化

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 第三个则是并发编程(72个知识点学习)

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

  • 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料

网易严选Java开发三面面经:HashMap+JVM+索引+消息队列

还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
的答案解析,生成了一份PDF文档

  • 第一个要分享给大家的就是算法和数据结构

[外链图片转存中…(img-JYc7tu5z-1713559504070)]

  • 第二个就是数据库的高频知识点与性能优化

[外链图片转存中…(img-mLTbK8F7-1713559504070)]

  • 第三个则是并发编程(72个知识点学习)

[外链图片转存中…(img-VBYWNIw6-1713559504071)]

  • 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料

[外链图片转存中…(img-ZwfpwtI3-1713559504072)]

还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-mR6Htewr-1713559504072)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值