当前位置: 首页 > article >正文

快速了解Java虚拟机(JVM)以及常见面试题(持续更新中

6、可分为新生代、老年代;

7、新生代更细化可分为Eden、

From Survivor、To Survivor,Eden:Survivor = 8:1:1

8、可通过-Xmx、-Xms调节堆大小;

9、无法再扩展

java.lang.OutOfMemoryError: Java heap space

GC垃圾回收机制:主要回收新生区和老年区

堆内存满,抛出,OOM错误。 JDK8之前叫永久存储区,JDK8之后叫元空间。 逻辑上存在,物理上不存在

新生区:

  • ​ 类诞生和成长,直到死亡的地方
  • ​ 所有的对象都在伊甸园区new出来

老年代:

·当新生代经历15次轻GC后还存在引用的,则被转移到老年代

永久区:

​ 永久区常驻内存,用来存放JDK自身携带的Class对象,interface元数据,存储的是Java运行的一些环境,这个区域不存在垃圾回收。关闭虚拟机时,释放这个区域的内存。

OOM:

​ -Xms:设置初始化分配内存大小 1/64 -Xmx:设置最大分配内存1/4

​ -XX:+PrintGCDetails GC清理垃圾信息 -XX:+HeapDumpOnOutOfMemoryError dumpOOM错误文件

​ 尝试扩大内存空间看结果,如果还有错误,分析代码是否出现垃圾代码或者死循环。

​ 内存快照分析工具,MAT,Jprofiler 作用:

①分析Dump内存文件,快速定位内存泄漏 ②获得堆中数据 ③获得最大对象

5、GC

作用区域:堆(堆+方法区(非堆)))

GC两种类型:轻GC 针对新生代和偶尔的幸存区(from,to) 重GC(全局GC)

GC的算法:标记清除法 不需要额外内存空间,两次扫描,浪费时间,产生内存碎片 、标记压缩,复制算法(新生代、伊甸园区 )伊甸园区和to区为空,引用计数器

GC算法总结:

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

内存整齐度:复制算法=标记压缩算法>标记清除

内存利用率:标记压缩算法=标记清除>复制算法

新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

  • 新生代回收器:Serial、ParNew、Parallel Scavenge
  • 老年代回收器:Serial Old、Parallel Old、CMS
  • 整堆回收器:G1

新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低;老年代回收器一般采用的是标记-整理的算法进行垃圾回收。

6、栈

特点及其作用:

1、线程私有;

2、方法执行会创建栈帧,存储局部变量表等信息;

3、方法执行入虚拟机栈,方法执行完出虚拟机栈;(先进后出)

4、栈深度大于虚拟机所允许StackOverflowError;

5、栈需扩展而无法申请空间OutOfMemoryError(比较少见);hotspot虚拟机没有;

6、栈里面运行方法,存放方法的局部变量名,变量名所指向的值(常量值、对象值等)都存放到堆上的;

7、栈一般都不设置大小,栈所占的空间其实很小,可以通过-Xss1M进行设置,如果不设置默认为1M;

8、随线程而生,随线程而灭;

9、该区域不会有GC回收。

二 、JVM面试总结


1、Java运行时,一个类是什么时候被加载的

1.1 类是通过什么加载的?

关于一个类什么时候开始被加载的问题,《Java虚拟机规范》中并没有进行强制约束,而是交给了虚拟机自己去自由实现。

1.2 有哪几种虚拟机?

​ 1)Sun公司最早的 Classic虚拟机;

​ 2)Sun/Oracle公司的HotSpot虚拟机;

​ 3)BEA公司的JRockit虚拟机;

​ 4)IBM公司的IBM J9虚拟机。

1.3.虚拟机是怎么工作的?

Java常用的虚拟机是HotSpot虚拟机,HotSpot虚拟机是按需加载(用什么类,加载什么类),在需要用到该类时会自动加载这个类。

ps:虚拟机加载类时,是按需加载,首先会加载rt.jar 包下的类,也就是 java.lang包下的类,也就是核心基础类库,然后加载main方法中所需要的类

2、JVM 一个类的加载过程

2.1 JVM一个类的加载分为几个阶段

一个类从加载到jvm内存,到从jvm内存卸载,它的整个生命周期会经历7个阶段

1)加载(Loading)

2)验证(Verification)

3)准备(Preparation)

4)解析(Resolution)

5)初始化(Initialization)

6)使用(Using)

7)卸载(Unloading)

2.2 他们之间的关系是怎样的?

其中验证、准备、解析三个阶段统称为连接(Linking);

在这里插入图片描述

2.3 每个阶段是做什么工作的?

加载:classpath、jar包、网络、某个磁盘位置下的类的class二进制字节流读进来,在内存中生成一个代表这个类的java.lang.Class对象放入元空间,此阶段我们程序员可以干预,我们可以自定义类加载器来实现类的加载;

验证:验证Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证虚拟机的安全;

准备:类变量赋默认初始值,int为0,long为0L,boolean为false,引用类型为null;常量赋正式值;

解析:把符号引用翻译为直接引用;

初始化:当我们new一个类的对象,访问一个类的静态属性,修改一个类的静态属性,调用一个类的静态方法,用反射API对一个类进行调用,初始化当前类,其父类也会被初始化… 那么这些都会触发类的初始化;

使用:使用这个类;

卸载

1.该类所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例;

2.加载该类的ClassLoader已经被GC;

3.该类的java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的方法。

3、类被初始化的过程

1.介绍类加载的过程

2.类的初始化阶段,Java虚拟机才真正开始执行类中编写的Java程序代码。

​ 准备阶段时,变量已经赋过一次系统要求的初始零值(默认值),而在初始化阶段,才真正初始化类变量和其他资源。

继承时父子类的初始化顺序是怎样的?

父类–静态变量

父类–静态初始化块

子类–静态变量

子类–静态初始化块

父类–变量

父类–初始化块

父类–构造器

子类–变量

子类–初始化块

子类–构造器

4、JVM中不同的类加载器加载哪些文件

1.启动类加载器(Bootstrap ClassLoader):(根的类加载器)C++语言实现的

<JAVA_HOME>\jre\lib\rt.jar,resources.jar、charsets.jar被-Xbootclasspath参数所指定的路径中存放的类库;

2、扩展类加载器(Extension ClassLoader):

<JAVA_HOME>\jre\lib\ext,被java.ext.dirs系统变量所指定的路径中所有的类库

3、应用程序类加载器(Application ClassLoader):系统的类加载器

AppClassLoader,加载用户类路径(ClassPath)上所有的类库

5、如何自定义自己的类加载器

1)继承ClassLoader

2)覆盖findClass(String name)方法 或者 loadClass() 方法;

findClass(String name)和loadClass() 方法有什么不同?

findClass(String name)方法:不会打破双亲委派;

loadClass() 方法:可以打破双亲委派。

6、了解Tomcat 的类加载机制吗

在这里插入图片描述

Tomcat自定义了WebAppClassLoader类加载器,打破了双亲委派的机制,即如果收到类加载的请求,首先会尝试自己去加载,如果找不到再交给父加载器去加载,目的就是为了优先加载Web应用自己定义的类。

为什么Tomcat要破坏双亲委派模型?

Tomcat是web容器,那么一个web容器可能需要部署多个应用程序。

1、部署在同一个Tomcat上的两个Web应用所使用的Java类库要相互隔离

2、部署在同一个Tomcat上的两个Web应用所使用的Java类库要互相共享

3、保证Tomcat服务器自身的安全,不受部署的Web应用程序影响;

4、需要支持JSP页面的热部署和热加载。

7、ClassLoader中的loadClass()、findClass()、defineClass()的区别

loadClass():

  • 主要进行类加载的方法,默认的双亲委派机制就实现在这个方法中.
  • 当我们想自定义一个类加载器并且想破坏双亲委派模型时,我们会重写loadClass()方法。

findClass():

  • 根据名称或位置加载.class字节码。
  • 如果你想定义一个自己的类加载器,并且要遵守双亲委派模型,那么可以继承ClassLoader,并且覆盖findClass()

http://www.kler.cn/a/528597.html

相关文章:

  • 【Python】第七弹---Python基础进阶:深入字典操作与文件处理技巧
  • BW AO/工作簿权限配置
  • MySQL 索引
  • WinDBG查找C++句柄泄露
  • 快速提升网站收录:利用网站分析工具
  • LeetCode:322.零钱兑换
  • python学习——常用的内置函数汇总
  • 2025年1月30日(Matlab 总结 `rm = 0:0.1:10;`)
  • 分析伏羲万年历
  • 4.攻防世界Web_php_include
  • 使用真实 Elasticsearch 进行高级集成测试
  • deep generative model stanford lecture note1 --- introduction
  • 8645 归并排序(非递归算法)
  • 工业相机如何获得更好的图像色彩
  • 常见数据丢失问题类型及解决方案
  • 前端 | 深入理解Promise
  • 蓝桥杯备赛经验帖
  • 图书管理系统 Axios 源码 __删除图书功能
  • Linux命令(144)之diff
  • [CVPR 2022]Cross-view Transformers for real-time Map-view Semantic Segmentation
  • Spring Boot项目如何使用MyBatis实现分页查询
  • 90,【6】攻防世界 WEB Web_php_unserialize
  • python-leetcode-完全二叉树的节点个数
  • webrtc协议详细解释
  • 完美还是完成?把握好度,辨证看待
  • 洛谷 P10289 [GESP样题 八级] 小杨的旅游 C++ 完整题解