JVM入门篇(面试前速补)

近期看看JVM,看了狂神说入门教学,总结下给大家。

文章目录

  • 1、JVM的位置
  • 2、JVM的结构体系
  • 3、类加载器及双亲委派机制
    • 3.1、类加载器作用
    • 3.2、类加载器类型
    • 3.3、双亲委派机制 *
  • 4、沙箱安全机制
  • 5、Native、方法区
    • 5.1、Native(本地方法栈引用) *
    • 5.2、PC寄存器
    • 5.3、方法区 *
  • 6、栈
  • 7、走近HotSpot和堆
    • 设置VM参数
  • 8、使用JPofiler工具分析OOM原因
  • 9、GC算法 *
    • 9.1、引用计数法
    • 9.2、复制算法
    • 9.3、标记压缩清除法
  • 总结
  • 面试点

1、JVM的位置

JVM处于操作系统之上,为Java程序在不同的系统平台上的运行提供便利,与硬件没有直接的交互。

2、JVM的结构体系

引用地址存在栈内,实际指向的内容存在堆中。

3、类加载器及双亲委派机制

3.1、类加载器作用

3.2、类加载器类型

  • 虚拟机自带的加载器

  • 启动器(根)加载器

  • 扩展类加载器

  • 应用程序加载器

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.3、双亲委派机制 *

类加载器负责加载类的字节码并创建对应的Class对象。双亲委派机制是指当一个类加载器收到类加载请求时,它会先将该请求委派给它的父类加载器去尝试加载。只有当父类加载器无法加载该类时,子类加载器才会尝试加载。

优点:

避免重复加载:通过委派给父类加载器,可以避免同一个类被多次加载,提高了加载效率。

安全性:通过双亲委派机制,核心类库由根加载器加载,可以确保核心类库的安全性,防止恶意代码替换核心类。

扩展性:开发人员可以自定义类加载器,实现特定的加载策略,从而扩展Java的类加载机制。

缺点:

灵活性受限:双亲委派机制对于某些特殊的类加载需求可能过于严格,限制了加载器的灵活性。

破坏隔离性:如果自定义类加载器不遵循双亲委派机制,可能会破坏类加载的隔离性,导致类冲突或安全性问题。

不适合动态更新:由于类加载器在加载类时会先检查父加载器是否已加载,因此在动态更新类时可能会出现问题,需要额外
的处理。

4、沙箱安全机制


5、Native、方法区

5.1、Native(本地方法栈引用) *

5.2、PC寄存器

5.3、方法区 *

static、final、Class模板、常量池

从Java 8开始,常量池从方法区转移到Java虚拟机堆内存之中

6、栈

栈:先进后出

队列:先进先出(FIFO:First Input First Output)

堆、栈、方法区:(从Java 8开始,常量池从方法区转移到Java虚拟机内存之中)

7、走近HotSpot和堆

Heap,一个JVM只有一个堆内存,堆内存的大小是可以调整的。

类加载器读取了类文件后,一般会把什么东西放到堆中呢?

类、方法、常量、变量~,保存我们所有引用类型的真实对象(实例对象)

堆内存中细分为三个区域:

  • 新生区(伊甸园区) Young/New

  • 养老区 old

  • 永久区 Perm

JDK8以后,永久存储区改名为元空间逻辑上存在(构思存在),物理上不存在

GC垃圾回收,主要是在伊甸园区和养老区~

假设内存满了,OOM,堆内存不够!

设置VM参数

public static void main(String[] args) {
    // 获取虚拟机试图使用最大内存
    long max = Runtime.getRuntime().maxMemory();
    // 获取Jvm内存
    long total = Runtime.getRuntime().totalMemory();

    System.out.println("max memory :" + max+" 字节,"+max/(double)1024/1024+"MB");
    System.out.println("total memory :" + total+" 字节,"+total/(double)1024/1024+"MB");
}
修改前:
max memory :3309305856 字节,3156.0MB
total memory :223346688 字节,213.0MB

修改后:(添加VM配置 -Xms1024m -Xmx1024m -XX:+PrintGCDetails)
max memory :1029177344 字节,981.5MB
total memory :1029177344 字节,981.5MB
Heap
 PSYoungGen      total 305664K, used 15729K [0x00000000eab00000, 0x0000000100000000, 0x0000000100000000)
  eden space 262144K, 6% used [0x00000000eab00000,0x00000000eba5c420,0x00000000fab00000)
  from space 43520K, 0% used [0x00000000fd580000,0x00000000fd580000,0x0000000100000000)
  to   space 43520K, 0% used [0x00000000fab00000,0x00000000fab00000,0x00000000fd580000)
 ParOldGen       total 699392K, used 0K [0x00000000c0000000, 0x00000000eab00000, 0x00000000eab00000)
  object space 699392K, 0% used [0x00000000c0000000,0x00000000c0000000,0x00000000eab00000)
 Metaspace       used 3432K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 370K, capacity 388K, committed 512K, reserved 1048576K

8、使用JPofiler工具分析OOM原因

下载JPofiler工具,安装idea的JPofiler插件

//-Xms 设置初始化内存分配大小
//-Xmx 设置最大分配内存
//-XX:+PrintGCDetails  打印GC垃圾回收信息
//-XX:+HeapDumpOnOutOfMemoryError  OOM时拿到内存快照文件
public class OOMTest {

    public static void main(String[] args) {

        ArrayList<OOMTest> list = new ArrayList<>();
        int count = 0;

        // 创建数组,一直扩大
        while (true) {
            list.add(new OOMTest());
            count ++;
        }
    }
}

VM参数加入 -Xms1m -Xmx2m -XX:+HeapDumpOnOutOfMemoryError (OOM时拿到内存快照文件)

运行后在项目根目录能拿到内存快照文件,打开后可以看线程转储这部分分析

由此可得出具体报错位置

9、GC算法 *

9.1、引用计数法

9.2、复制算法

  • 好处:没有内存碎片
  • 坏处:浪费空间,多了一半内存空间永远是空to
  • 使用场景:对象存活率较低的情况下(新生区)

9.3、标记压缩清除法

标记清除法

优点:不需要额外的空间

缺点:两次扫描,严重浪费时间,会产生内存碎片

优化:增加压缩(标记压缩算法)

总结

内存效率:复制算法>标记清除>标记压缩(时间复杂度)
内存整齐度:复制算法=标记压缩算法>标记清除算法
内存利用率:标记压缩算法=标记清除算法>复制算法

没有最优算法。只有最合适的算法。

所以GC的好处:分代收集算法
年轻代:存活率低,用复制算法
老年代:存活率高,区域大,用标记清除+标记压缩混合实现(标记清除n次,进行标记压缩)

面试点

JVM的内存模型和分区~详细到每个区放什么?

JVM 分为堆区和栈区,还有方法区

堆区 存对象实例、数组、常量池(从Java 8开始,常量池从方法区转移到Java虚拟机堆内存之中)等

栈区 存引用地址,八大基础数据类型(局部变量),实例方法

方法区 存 static、final、Class模板

堆里面的分区有哪些?Eden,form,to,老年区,说说他们的特点?

堆分为年轻代(伊甸园区,幸存区0和1)和老年代两个分区(元空间是逻辑上存在)

Eden区(伊甸园区)是年轻代中最大的一个区域,用于存放新创建的对象。当一个对象被创建时,首先会被分配到Eden区。当满员触发GC存活对象会放置幸存区;

Survivor区是年轻代中的两个区域之一,一般称为From区和To区。伊甸园区GC存活的的会转至幸存区的From区,下次GC时若存活则复制至To区(谁空或谁少为to区)

老年区是年轻代中对象经过多次轻GC仍然存活的对象所存放的区域,老年区的对象生命周期较长,因此老年区的垃圾回收频率较低,当需要GC是重GC(Full
GC),会对整个堆内存进行回收。

GC的算法有哪些?标记清除法,标记压缩,复制算法,引用计数法,怎么用?

GC(分代收集法)的算法(GC的作用域是堆和方法区):标记清除法、标记压缩法、复制算法、引用计数法

引用计数法:各个对象每用一次,该对象计数器就+1(计数器本身也要有消耗)。当计数器为0时,说明该对象没有,就立刻进行垃圾回收。

复制算法:(年轻代主要用到复制算法:Eden区和幸存者区,要知道幸存区分为from和to两个区域:哪一个区域是空哪一个区域就是to区。)

标记清除:先扫描对象,对活着的对象进行标记。然后开始清除,对没有标记的对象进行清除

标记压缩:在标记清除的基础上再次扫描,向一端移动所有存活的对象(减少了内存碎片)

轻GC和重GC分别在什么时候发生?

法、引用计数法**

引用计数法:各个对象每用一次,该对象计数器就+1(计数器本身也要有消耗)。当计数器为0时,说明该对象没有,就立刻进行垃圾回收。

复制算法:(年轻代主要用到复制算法:Eden区和幸存者区,要知道幸存区分为from和to两个区域:哪一个区域是空哪一个区域就是to区。)

标记清除:先扫描对象,对活着的对象进行标记。然后开始清除,对没有标记的对象进行清除

标记压缩:在标记清除的基础上再次扫描,向一端移动所有存活的对象(减少了内存碎片)

轻GC和重GC分别在什么时候发生?

轻GC一般发生在 新生代和幸存区,重GC一般发生在老年代

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445014.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VMware 安装 MS-DOS 6.22

VMware 安装 MS-DOS 6.22 0. 准备工作创建虚拟机下载安装包装入安装软盘 1. 安装界面2. 创建分区3. 格式化分区4. 安装参考资料 提醒&#xff1a;如果你是为了 int 13 来的&#xff0c;我试了没用 0. 准备工作 创建虚拟机 先创建一个 DOS 虚拟机右健我们创建的DOS 虚拟机 >…

STM32使用标准库编写外部时钟控制oled显示计数(proteus仿真)

这节课的结果是在上节课的基础上更改的&#xff1a;电路图为&#xff1a;用一个开关来模拟外部时钟的高低电平的变化。 当然也可以配置一个外部时钟来模拟&#xff0c;也是可以的&#xff1a; 由于这节课的代码是在上节课的基础上有一点修改而来的&#xff0c;所以就只把更改的…

BC134 蛇形矩阵

一&#xff1a;题目 二&#xff1a;思路分析 2.1 蛇形矩阵含义 首先&#xff0c;这道题我们要根据这个示例&#xff0c;找到蛇形矩阵是怎么移动的 这是&#xff0c;我们可以标记一下每次移动到方向 我们根据上图可以看出&#xff0c;蛇形矩阵一共有两种方向&#xff0c;橙色…

win10阿里云实现内网穿透#frp

win10&阿里云实现内网穿透#frp 文章目录 win10&阿里云实现内网穿透#frp一、什么是内网穿透&#xff1f;下载frp 二、云服务端部署frps三、本地部署frpc 一、什么是内网穿透&#xff1f; 内网穿透是一种网络技术&#xff0c;它允许外部网络用户通过互联网访问局域网&am…

input中文输入法导致的高频事件

这是基本结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>中文输入法的高频事件</title&…

指针篇章-(冒泡排序详解)

冒泡排序 图解 tmp图解 内容图解 每次循环的次数减少 for循环详解 冒泡排序是一种简单的排序算法&#xff0c;它重复地遍历要排序的数列&#xff0c; 一次比较两个元素&#xff0c;如果它们的顺序错误就把它们交换过来。 遍历数列的工作是重复地进行直到没有再需要交换&…

C# CallerMemberName、CallerFilePath、CallerLineNumber

CallerMemberName&#xff1a;调用某个方法的主方法名称 CallerFilePath&#xff1a;调用某个方法的主方法所在的类文件地址 CallerLineNumber&#xff1a;调用这个方法所在的行号 用这三个附加属性&#xff0c;需要设置默认值。

element-ui plus v2.60 终于修复了 radio checkbox 取值不明确的问题,label value 值

element-ui plus v2.60 终于修复了 radio checkbox 取值不明确的问题&#xff0c;label value 值 昨天想反馈这个关于 label 和 value 的问题的时候&#xff0c;发现新版本已经修正这个问题了。 一、ElementUI 旧版关于 label 和 value 的问题 从之前 element-ui 用过来的&a…

c++ 串口通信库

根据资料整理的串口通信库&#xff0c;封装成为了动态库&#xff0c;使用者只需要调用接口即可 使用实例如下&#xff1a; //接受数据 void CSerialPortCommonLibDemoDlg::OnReceive() { char * str NULL; str new char[256]; _port.readAllData(str); CString s…

回溯算法12-全排列II(Java/排列数去重操作)

12.全排列II 题目描述 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,2] 输出&#xff1a; [[1,1,2],[1,2,1],[2,1,1]]示例 2&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&…

macOS系统浏览器设置“检查元素“功能

目录 第一步 点击Safari浏览器&#xff0c;选择"设置" 第二步 选择高级&#xff0c;参照下图勾选"在菜单栏中显示开发菜单" 类似于windows系统的f12快捷键。Mac默认是不支持f12的&#xff0c;右键也没有"检查元素"&#xff0c;如果需要使用&am…

英伟达jetson nano第一次进入镜像配置

我所用产品为jetbot Ubuntu18.04LTS CtrlAltT启动终端 设置分辨率 xrandr –output HDMI-0 –mode “1920x1080” 最好在设置中重新配置下 不然重启又得调 联网-更新语言包 reboot重启

动态规划课堂4-----子数组系列

目录 引入&#xff1a; 例题1&#xff1a;最大子数组和 例题2&#xff1a;环形子数组的最大和 例题3&#xff1a;乘积最大子数组 例题4&#xff1a;乘积为正数的最长子数组 总结&#xff1a; 结语&#xff1a; 引入&#xff1a; 在动态规划&#xff08;DP&#xff09;子…

kibana 上dashbord 和discover 时间快 or 慢 8小时,处理方案

今天遇到了一个问题。在es库中的数据的时间是正确的。但是在kibana的discover展示页面上是错误的&#xff0c;错了8个小时。我这里是快了8个小时。这个问题非常难受&#xff0c;因为看起来&#xff0c;总是差8个小时&#xff0c;特别是查看日志的时候&#xff0c;总有一种错觉&…

AHU 汇编 实验一

一、实验名称&#xff1a;实验1 实验1 用Debug命令查看寄存器和内存中的内容 实验目的:求掌握使用Debug命令查看寄存器和内存的方法。 通过第2章两个简单实例认识汇编语言程序&#xff0c;初步了解程序格式&#xff1b;段定义&#xff1b;标号&#xff1b;DOS系统功能&#xf…

Anaconda prompt运行打开jupyter notebook 指令出错解决方案

一、打不开jupyter notebook网页 报错如下&#xff1a; Traceback (most recent call last): File “D:\anaconda3\lib\site-packages\notebook\traittypes.py”, line 235, in _resolve_classes klass self._resolve_string(klass) File “C:\Users\DELL\AppData\Roaming\Py…

Imagination:RISC-V CPU的重要力量

根据SHD集团最近发布的报告显示&#xff0c;RISC-V正全速发展中。通过分析从2021年到2030年这十年间RISC-V核在不同应用和功能领域的潜在市场&#xff0c;作者Rich Wawrzyniak得出结论称&#xff0c;到2030年&#xff0c;22.3%的SoC将包含RISC-V CPU&#xff0c;RISC-V的收入预…

【工具使用-VScode】VScode如何设置空格和tab键显示

一&#xff0c;简介 在提交代码的时候&#xff0c;行末尾的tab和空格不符合规范&#xff0c;但是如果在vscode中不显示tab和空格的话&#xff0c;不能及时的查看到并改正&#xff0c;导致提交代码之后还需要再次进行修改&#xff0c;效率比较低。 代码编辑界面如图所示&#…

【Node.js】-闲聊:前端框架发展史

前端框架的发展史是一个不断演进和创新的过程&#xff0c;旨在提高开发效率、优化用户体验&#xff0c;并推动前端技术的不断发展。以下是前端框架发展的主要阶段和关键里程碑&#xff1a; 早期阶段&#xff1a; 在这个阶段&#xff0c;前端主要由HTML、CSS和JavaScript等基础技…

修改简化docker命令

修改|简化docker命令 使用命令打开 .bashrc 文件&#xff1a; vim ~/.bashrc在文件中添加类似以下行来创建别名&#xff1a; # 查看所有容器 alias disdocker images # 查看运行容器 alias dpsdocker ps # 查看所有容器 alias dpsadocker ps -a # 停止容器 alias dsdocker s…