java面经总结-jvm相关

一.谈谈你对java的理解

  1. 平台无关性
    在程序运行前,Java源代码(.java)需要经过编译器编译成字节码(.class)。在程序运行时,JVM负责将字节码翻译成特定平台下的机器码并运行,也就是说,只要在不同的平台上安装对应的JVM,就可以运行字节码文件。
    同一份Java源代码在不同的平台上运行,它不需要做任何的改变,并且只需要编译一次。而编译好的字节码,是通过JVM这个中间的“桥梁”实现跨平台的,JVM是与平台相关的软件,它能将统一的字节码翻译成该平台的机器码。
  2. gc特性
  3. 语言特性
  4. 面向对象
  5. 类库
  6. 异常处理

二.jvm如何加载.class文件
在这里插入图片描述

Class Loader:依据特定格式,加载class文件到内存
Execution Engine:对命令进行解析
Native Interface:融合不同开发语言的原生库为java所用
Runtime Dara Area:JVM内存空间结构模型

三.反射
java反射机制是在运行的过程中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LJiuiqL1-1647406389805)(/upload/2022/03/image-94b3699d2fa44862b3d4be95cb33211e.png)]
getDeclaredMethod:只能获取本类的所有的方法,不能获取继承,实现的方法
getmethod:可以获取所有的的方法包括继承,实现的方法

四.类从编译到执行的过程
编译器将java源文件编译为.class字节码文件,ClassLoader将字节码转换称为JVM中的Class对象,JVM利用Class对象实例化为对应的对象。
ClassLoader的种类:
BootStrapClassLoader:加载核心库java
ExtClassLoader:加载扩展库javax
AppClassLoader:加载程序所在目录
自定义类加载器

五.类加载器的双亲委派机制

假设用户刚刚摸鱼写的Test类想进行加载,这个时候首先会发送给应用程序类加载器AppCloassLoader;

然后AppClassLoader并不会直接去加载Test类,而是会委派于父类加载器完成此操作,也就是ExtClassLoader;

ExtClassLoader同样也不会直接去加载Test类,而是会继续委派于父类加载器完成,也就是BootstrapClassLoader;

BootstrapClassLoader这个时候已经到顶层了,没有父类加载器了,所以BootstrapClassLoader会在jdk/lib目录下去搜索是否存在,因为这里是用户自己写的Test类,是不会存在于jdk下的,所以这个时候会给子类加载器一个反馈。

ExtClassLoader收到父类加载器发送的反馈,知道了父类加载器并没有找到对应的类,爸爸靠不住,就只能自己来加载了,结果显而易见,自己也不行,没办法,只能给更下面的子类加载器了。

AppClassLoader收到父类加载器的反馈,顿时明白,原来爸爸虽然是爸爸,但是他终究不能管儿子的私事,所以这时候,AppClassLoader就自己尝试去加载。

结果,就这样成功了,走了一大圈,兜兜转转还是自己干。

使用双亲委派机制去加载类,是为了避免多份同样字节码的加载,

六.类的加载方法
隐式加载:new
显示加载:loadclass(是还没有链接的),forname(得到的class是已经初始化完成的)
类的装载过程
加载:通过classloader加载class文件字节码,生成class对象
链接:
1.校验:检查加载的class的正确性和安全
2.准备:为类变量分配存储空间并设置类变量初始值
3.解析:jvm将常量池内的符号引用转换成直接引用
初始化:执行类变量赋值和静态代码块

七.java内存模型
在这里插入图片描述

从线程来看
在这里插入图片描述

程序计数器:
当前线程所执行的字节码行号指示器
改变计数器的值来选取下一条需要执行的字节码指令
和线程是一对一的关系即:线程私有
对java方法计数,如果是native方法则计数器值为undefined
不会发生内存泄漏

java虚拟机栈
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iqfdBI0k-1647406389808)(/upload/2022/03/image-ba04a51bdcd3479d8123e568dc22be19.png)]
java方法执行的内存模型
包含多个栈帧

元空间和永久代
元空间使用的是本地内存,而永久代使用的是jvm的内存

元空间比永久代的优势:
字符串常量池存在永久代中,容易出现性能问题和内存溢出
类和方法的信息大小难以确定,给永久代的大小指定带来困难
永久代会为gc带来不要的复杂性

java堆
对象实例的分配区域

JVM三大性能调优参数 -xms -xmx -xss的含义
xss:规定了每个线程虚拟机栈的大小
xms:堆的初始值
xmx:堆能达到的最大值

内存抖动现象:指在短时间内由大量的对象被创建或者被回收的现象
原因:主要是频繁在循环里创建对象。
后果:会导致gc机制频繁运行,造成系统的卡顿

内存分配策略:
静态存储:编译时确定每个数据目标在运行时的存储空间需求
栈式存储:数据区需求在编译时未知,运行时模块入口前确定
堆式存储:编译时或运行时模块入口都无法确定,动态分配

堆栈之间的区别:
管理方式:栈自动释放,堆需要gc
空间大小:栈比堆小
碎片相关:栈产生的碎片远小于堆
分配方式:栈支持静态和动态分配,而堆仅仅支持动态分配
效率:栈的效率比堆高

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值