小白都能看懂的 JVM 知识,一文带你学会 JVM 内存模型!

JVM 是 JavaVirtual Machine 的简称,是 Java 虚拟机,是一种模拟出来的虚拟计算机,它通过在不同的计算机环境当中模拟实现计算功能来实现的。

引入 Java 虚拟机后,Java 语言在不同平台上运行时就不需要重新编译。在其中,Java 虚拟机屏蔽了与具体平台的相关信息,使得 Java 源程序在编译完成之后即可在不同的平台运行,达到“一次编译,到处运行”的目的,Java 语言重要的特点之一跨平台,也即与平台的无关性,其关键点就是 JVM。

1.3.2 JRE 的简介

JRE 是 JavaRuntime Environment 的简称,是 Java 运行环境,是让操作系统运行 Java 应用程序的环境,其内部包含 JVM,也就是说 JRE 只负责对已经存在的 Java 源程序进行运行的操作,它不包含开发工具 JDK,对 JDK 内部的编译器、调试器和其它工具均不包含。

1.3.3 JDK 的简介

JDK 是 JavaDevelopment Kit 的简称,是 Java 开发工具包,是整个 Java 程序开发的核心。其主要包含了 JRE、Java 的系统类库以及对 Java 程序进行编译以及运行的工具,例如:javac.exe 和 java.exe 命令工具等。

1.4 JVM 的常见实现


Oracle(Hotspot、Jrockit)、BEA(LiquidVM)、IBM(J9)、taobaoVM(淘宝专用,对 Hotspot 进行了深度定制)、zing(垃圾回收机制非常快,到达 1 毫秒左右)。

1.5 JVM 的内存结构图


当 Java 程序编译完成为.class 文件==》类加载器(ClassLoader)==》将字节码文件加载进 JVM 中;

1.5.1 方法区、堆

方法区中保存的主要是类的信息(类的属性、成员变量、构造函数等)、堆(创建的对象)。

1.5.2 虚拟机栈、程序计数器、本地方法栈

堆中的对象调用方法时,方法会运行在虚拟机栈、程序计数器、本地方法栈中。

1.5.3 执行引擎

执行方法中代码时,代码通过执行引擎执行中的“解释器”执行;方法中经常调用的代码,即热点代码,通过“即时编译器”执行,其执行速度非常快。

1.5.4 GC(垃圾回收机制)

GC 是针对堆内存中没有引用的对象进行回收,可以手动也可以自动。

1.5.5 本地方法接口

因为 JVM 不能直接调用操作系统的功能,只能通过本地方法接口来调用操作系统的功能。

2. JVM 内存结构-程序计数器

==================

2.1 程序计数器的定义


Program Counter Register 即程序计数器(寄存器),用于记录下一条 Jvm 指令的执行地址。

2.2 操作步骤


javap 主要用于操作 JVM,javap -c 是对 java 代码进行反汇编操作。下图为通过先编译 demo.java 后,再执行 javap -c demo 的输出结果:

其中第一列为二进制字节码,即 JVM 指令,第二列为 java 源代码。第一列中的序号为 JVM 指令的执行地址。

JVM 会通过程序计数器记录下一条需要执行的 JVM 指令的地址(比如第一行的 0),然后交给解释器解析为机器码,最后交给 cpu(只能识别机器码),完成一行的执行。

想要执行下一行,继续让 JVM 的程序计数器记录下一条地址(比如第二行的 3),再交给解释器解析后给 cpu,以此类推执行结束。

2.3 特点


2.3.1 线程私有的

2.3.2 不会存在内存溢出

3. JVM 内存结构-虚拟机栈

=================

3.1 定义


虚拟机栈是每个线程运行所需要的内存空间,每个栈中由多个栈帧组成,每个线程中只能有一个活动栈帧(对应当前正在执行的方法),所有栈帧都遵循后进先出,先进后出的原则。

栈帧是每次调用方法时所占用的内存,在栈帧中保存的内容参数、局部变量、返回地址。

注 1:垃圾回收不涉及栈内存,因为栈内存是由方法调用产生的,当方法调用结束后会弹出栈。

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

注 3:方法的局部变量,当其没有逃离方法的作用范围时,是线程安全的;如果其引用了对象(比如静态变量,即共享变量,用对象作为参数的方法,返回值为对象的方法),并且逃离出了方法的作用范围,就需要考虑线程安全的问题了。

3.2 栈内存溢出


3.2.1 发生原因

(1)虚拟机栈中,栈帧过多(无限递归),如图 1 栈帧过多;

(2)每个栈帧所占用过大,如图 2 栈帧过大。

3.2.2 栈内存溢出小实验

3.2.2.1 栈帧过多的小实验

无限递归调用(栈帧过多)的小实验,method1()方法在主方法中无限调用自己,那么会发生什么情况呢?

答案很明显,程序崩溃了,产生了栈内存溢出错误,如下图所示:

-Xss:该参数规定了每个线程虚拟机栈的大小;

接着我们通过设置一个虚拟机栈的大小是 256k 试试会发生什么?

我们发现当我们调整了虚拟机栈的大小后执行了 4315 次方法后内存就溢出了,而调整虚拟机栈之前,我们是 23268 次,很明显我们可以通过-Xss 参数调整虚拟机栈的大小来控制内存的溢出情况。

3.2.2.2 线程运行诊断小实验

想象中的场景,大佬在疯狂输出,突然 CPU 爆表了,显示 CPU 占用过多,如何去定位哪行代码的问题,是的是哪行(大佬都很忙的好吗,当然要精确了,一分钟几千万上下的,O(∩_∩)O 哈哈~)?

Linux 环境下:

在后台运行 Stack_6 这个 java 字节码(.class)文件:

注:无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。

(1)通过 top 命令,查看进程(相当于任务管理器),发现了一个占用 CPU 达到 100%的可疑家伙,这还了得,赶紧瞅瞅具体发生了什么,还有没有王法,这让其他小伙伴还怎么愉快的玩耍,秒速纠错 ING。。。

top 命令,查看哪个进程占用 CPU 过高,返回进程号。

(2) 通过 ps H -eo pid,tid ,%cpu | grep 命令过滤任务管理器中的内容。

注:ps H -eopid,tid,%cpu |grep,是通过 ps 命令查看哪个线程占用 CPU 过高,返回进程 id,其中 pid 为进程 id,tid 为线程 id,%cpu 为 CPU 占用情况;

发现了罪魁祸首,这一串串心惊肉跳的红色。。。

(3) 通过 jstack 进程 id 查看,20389 这个有问题的进程中具体的情况。

注:jstack 进程 id,是通过 jstack 命令定位具体哪段代码出现占用 CPU 过高,注意 jstack 命令查找的线程 id 是 16 进制的,需要转换;

发现里面有一堆执行的代码,那么我们怎么找到具体是哪个家伙搞事情的呢?上图我们可以发现搞事情的线程是 20441,那么我们通过计算器将 20441 转换为 16 进制的 4FD9 再去试试,真相只有一个。

通过对比 nid(线程 id)4fd9,我们发现这个叫 thread1 的线程一直在运行(RUNNABLE 状态),并且查看到位置是位于 Stack_6.java 文件的第 11 行出现的问题。。。

现在我们回到源码中,在 Stack_6 文件的第 11 行,我们发现原来这里一直在执行死循环,终于找到你,还好我没放弃,奈斯~

4. JVM 内存结构-本地方法栈

==================

4.1 定义


由于 Java 本身有时候是无法直接和操作系统底层交互的,但有时候需要 Java 调用本地的 C 或 C++方法,所以此时本地方法栈应运而生,它们是一类带有 native 关键字的方法。

5. JVM 内存结构-堆

==============

5.1 定义


Heap 堆:是通过 new 关键字创建的对象存放在堆中

5.2 特点


5.2.1 线程共享

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

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

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

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

《MySql面试专题》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySql性能优化的21个最佳实践》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

《MySQL高级知识笔记》

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

关注我,点赞本文给更多有需要的人
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
2432241785)]

[外链图片转存中…(img-CDwf5UPC-1712432241785)]

[外链图片转存中…(img-lYNt7gw7-1712432241786)]

[外链图片转存中…(img-gEwW6GlA-1712432241786)]

[外链图片转存中…(img-zOiOJK30-1712432241786)]

文中展示的资料包括:**《MySql思维导图》《MySql核心笔记》《MySql调优笔记》《MySql面试专题》《MySql性能优化的21个最佳实践》《MySq高级知识笔记》**如下图

[外链图片转存中…(img-G16ZOID2-1712432241786)]

关注我,点赞本文给更多有需要的人
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值