大厂必问的JVM面试题

本文目录:

  • 讲一下JVM内存结构?

    • 程序计数器
    • 虚拟机栈
    • 本地方法栈
    • 方法区
    • 运行时常量池
    • 直接内存
  • Java对象的定位方式
  • 说一下堆栈的区别?
  • 什么情况下会发生栈溢出?
  • 类文件结构
  • 什么是类加载?类加载的过程?
  • 什么是双亲委派模型?
  • 为什么需要双亲委派模型?
  • 什么是类加载器,类加载器有哪些?
  • 类的实例化顺索引是什么意思序?
  • 如何判断一个对象是否存活?
  • 可作为GC Roots的对象有哪些?
  • 什么情况下类会被卸载?
  • 强引用、软引用、弱引用、虚引用是什么,有什么区别?
  • Minor GC 和 Full GC的区别?
  • javascript存的分配策略?
  • Full GC 的触发条件?
  • 垃圾回收算法有哪些?
  • 有哪些垃圾回收器?
  • java面试题用的 JVM 调优的命令都有哪些?
  • 对象头了解吗?
  • 如何排查 OOM 的问题?
  • GC是什么?为什么要GC?

本文已经收录到gi编译器系统软件thub仓库,此仓库用于分享互联网大厂高频面试题、Java核心知识总结,包括Jjavascriptava基础、并发安全期计算器、MySQL、Springboot、MyBatis、Redis、Ra索引bbitMQ等等,面试必备!欢迎大家star索引失效
github地址:https://github.com/Tyson0314/Java-learning

讲一下JVM内存结构?

JVM内存结构分为5大区域,程序计数器虚拟机栈本地方法栈方法区ued2娱乐问33300

大厂必问的JVM面试题

程序计数器

线程私有的,作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址。程序计数器主要有两个作用:

  1. 当前线程所执行的字节码的行号指示器,通过它实现代码的流程控制,如:顺序执行、选择、循环、异常处javascript理。
  2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,当线程被切换回来的时候能够知道它上次执行的位置。

程序计数器是唯一一java怎么读个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程监控怎么安装的结束而死亡。

虚拟机栈

Java 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表操作数动态链接方法出口信息。每一次函数调用都会有一个对应的栈帧被压入虚拟机栈,监控摄像头怎么连接手机每一个函数调用结束后,都会有一个栈帧被弹出。

局部变量表是存储用于存放方法参数和方法内的局部变量。

每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,在方法调用过程中,会进行动态链接,将这个符号引用转化为直接引用。

  • 部分符号引用在类加载阶段的时候就转化为直接引用,这种转化就是静态链接
  • 部分符号引编解码器是什么意思用在运行期间转化为直接引用,这种转化就是存储过程动态链接

Java 虚拟机栈也是线程私有的,每个线程都有各自的 Java 虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡。Java 虚拟机栈会出现两种错误:Stackued2主管找扣或徽22212OverFl监控appowErrorOutOfMemoryError

可以c#委托通过 -Xss 参数来指定每个线程的虚拟机栈内存大小:

java -Xss2M

本地方法栈

虚拟机栈为虚拟机执行 Java 方法服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。Native 方法一般是用其它语言(C、C++等)编写的。

本地方法被执行的时候索引类型,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。

堆用java于存放对象实例,是垃圾收集器管理的主要区域,因此也被称作GC堆。堆可以细分为:新生代(Eden空间、From Sur存储器vivorTo Survivor空间)和老年代。

通过 -Xms设定程序启动时占用内存大小,通过-Xmx设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会java语言抛出OutOfjava模拟器Memory异常。

java -Xms1M -Xmx2M

方法区

方法区与 Java 堆一样,是编译器作用各个线程共享的内存区域,它用于存储已安全教育被虚拟机加载的类信息、常存储单元量、静态变量、即时编译器编译后的代码等数据。

对方法区进行垃圾回收的主要目标是对常量池的回收和对类的卸载

永久代

方法区是 JVM 的规范,而永久代PermGen是方法区的一种实现方式,并且只有 HotSpot 有永久代。对于其他类型的虚拟机,如JRockit没有永久代。由于方法区主要存储类的相关信息,所以对于动态生成类的场景比较容易出现永久代的内存溢出。

元空间

JDK 1.8 的时候,HotSpot的永久代被彻底移除了,使用元空间替代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。两者最大的区别在于:元空间并不在虚拟机中,而是使用直接内存。

为什么要将永久代替换为元空间呢?

永久代内存受限于 JVM 可用内存,而元空间使用的是直接内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是相比永久代内存溢出的概率更小。

运行时常量池

运行时常量池是方法区的一部分索引符号表示的含义,在类加载之后,会将编译器生成的各种字面量和符号引号放到运行时常量池。在运行期间编解码器不可用动态生成的常量,java面试题如 String 类的 intern()方法,也会被放入运行时常量池。

大厂必问的JVM面试题

大厂必问的JVM面试题

大厂必问的JVM面试题

图片来源:https://blog.csdn.net/soonfly

直接内存

直接内存并不是虚拟机运行时java培训数据区的一部分,也不是监控摄像头虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemued2娱乐问33300oryError 错误出现。

NIO的Buffer提供了DirectBuffer,可以直接访问系统物理内存,避免堆内内存到堆外内存的数据拷贝操作,提高效率。DirectBuffer直接分配在物理内存中,并不占用堆空间,其可申请的最大内存受操作系统限制,不受最大堆内存的限制。

直接内存的读写操作比堆内存快,可以提升程序I/O操作的性c#能。通常在I/O通信过程中,会存在堆内内存到堆外内存的数据拷贝操作,对于需要频繁进行内存间数据拷贝且生命周期较短的暂存数索引失效据,都建议存储到直接内存。

Java对象的定位方式

Java 程序通过栈上的 reference 数据来操作堆上java环境变量配置的具体对象。对象的访问方式由虚拟机实现而定,目前主流的访问方式有使用句柄和直接指针两种:

  • 如果使用算法的有穷性是指句柄的话,那么 Java 堆中将会划分出一块内存来作为句柄池,re监控摄像头ference 中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息。使用句柄来ued2招商找33300访问的最大好处是 reference 中存存储器中存取速度最快的是储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而 reference 本身不需要修改。
  • 直接指针。reference索引符号表示的含义 中存储的直接就是对象的地址。对象包含到对象类型数据的指针,通过这个指针可以访问对象类型数据。使用直接指针访问方式最大的好处c#就是访问对象速度快,它节省了一次指针定位的时间开销,安全生产法虚拟机hotspot主要是使用直接指针来访问对象。

说一下堆栈的区别?

  1. 堆的物理地址分配是不连算法工程师续的,性能较慢;栈的物理地址分配是连续的,性能相对较快。
  2. 堆存放的安全教育平台登录对象的实例和数组;栈存放的是局部变量,操作数栈,返回结果等。
  3. 堆是线程共享的;栈是线存储程私有的。

什么情况下会发生栈溢出?

  • 当线程请求的栈深度超过了虚拟机允许的最大深度时,会抛出StackOver监控摄像头怎么连接手机FlowError异常。这种情况通常是因为方法递归没终止条件。
  • 新建线程的时候没有足够的内存去创建对应的虚拟机栈,虚拟机会抛出OutOfMemoryError异常。c#为什么用的人很少比如线程javascript启动过多就会出现这种情况存储

类文件结构

Class 文件结构如下:

ClassFile {
u4             magic; //类文件的标志
u2             minor_version;//小版本号
u2             major_version;//大版本号
u2             constant_pool_count;//常量池的数量
cp_info        constant_pool[constant_pool_count-1];//常量池
u2             access_flags;//类的访问标记
u2             this_class;//当前类的索引
u2             super_class;//父类
u2             interfaces_count;//接口
u2             interfaces[interfaces_count];//一个类可以实现多个接口
u2             fields_count;//字段属性
field_info     fields[fields_count];//一个类会可以有个字段
u2             methods_count;//方法数量
method_info    methods[methods_count];//一个类可以有个多个方法
u2             attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
}

主要参数如下:

魔数class文件标志。

文件版本:高版本的 Java 虚拟机可以执行低版本编译器生成的类文件,但c#面试题是低版本的 Java 虚拟机不能执行高版本编译器生成的类文件。

常量池:存放字面量和符号引存储用。字面量类似于 Java 的常量,如字符串,声明为final的常量值等。符号引用包含三类:类和接口的全限定名,方法的名称和描述符,字段的名称和描述符。

访问标志:识别类或者接口的访问信息,比如这个Classc#面试题类还是接口,是否为 public 或者 ajavascriptbstract 类型等等。

当前类的索引:类索引用于确定这javaee个类的全限定名。

什么是类加载?索引符号表示的含义类加载的过程监控摄像头

类的加载索引超出矩阵维度指的是将类的class文件中的二进制数据读入到监控摄像头内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个此类的对象,通过c#是什么这个对象可以访问到方法区对应的类信息。

大厂必问的JVM面试题

加载

  1. 通过类的全限定名获取定义此类的二进制字节流
  2. 将字节c#委托流所代表的静态存储结构转换为方法区的运行时数据结构
  3. 在内存中生ued2主管找扣或徽22212成一个代表该类的Class对象,作为方法区类信息的访问入口

验证

确保Class文存储件的字节流中编译器是什么意思包含的信息符合虚拟机规范,保证在运行后不会危害虚拟机自身的安全。主要包括四种验证:文件格式验证,元数据验证,字节码验证,符号引用验证

准备

为类变量分配内存并设置类变量初始值的阶段。

解析

虚拟机将常量池索引图内的符号引用替换为直接引用的过程。符号引用用于描述目标,直接引用直接指向目标的地址。

初始化

开始执行类中定义的Java代码,初始化阶段是调用类构造器的过程。

什么是双亲委派模型?

一个类加载器收到一个类的加载请求时,它首先不会自己c#委托尝试去加载它,而是把这个请求委派给父类加载器去完成,这样层层委派,因此所有的加载请求最终都会传送到顶层的启动类加载器索引超出矩阵维度中,只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加载。

大厂必问的JVM面试题

双亲委派模型的具体实现代码在 ja存储处理国家秘密的计算机信息va.lang.ClassLojavaader中,此类的 loadClass() 方法运行过程如下:先检查类是否已经加载过,如果没有则让父类加载器去加载。当父类java怎么读加载器加载失败时抛出 ClassNotFoundException,此时尝试自己去加载。源码如下:

public abstract class ClassLoader {
// The parent class loader for delegation
private final ClassLoader parent;
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
}

为什么需要双亲委派模型?

双亲委派模算法导论型的好处:可以防止内存中安全教育平台登录出现多份同样的字节码。如果没有双亲委派模型而是由各个类加载器自行加载的话,如果用户编写了一个java.lang.Object的同名类并放在ClassPath中,多个类加载器都去加载这个类到内存中,系统中将会出现多个不同的Object类,那么类之间的比较结果及类的唯一性将无法保证。

什么是类加载器,类加载器有哪些?

  • 实现通过类的全限定名java模拟器获取该类的二进制字节流的代码块叫做类加载器。

    主要有一下四种类加载器:算法导论

    • 启动类存储器中存取速度最快的是加载器:用来加载 Java 核心类库ued设计,无法被 Java 程序直接引用。
    • 扩展类加载器:它用来加载 Java 的扩展库。Java 虚拟索引金枝机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
    • 系统类加载器:它根据应用的类路径来加载 Java 类。可通过ClassLoader.getSystemClassLoader()获取它。
    • 自定义类加载器:通过继承java.lang.ClassLoader类的方式实现。

类的实例化顺序?

  1. 父类中的stati算法的时间复杂度是指什么c代码块,当前类的static代码块
  2. 父类的普通代码块
  3. 父类的构造函数
  4. 当前类普通代码块
  5. 索引符号前类的构造函数

如何判断一个对象是否存活?

对堆垃圾回收前的第安全期计算器一步就是要判断那些对象已经死亡(即不再被任何途径引用的对象)。判断对象是否存活有两种方法:引用计数法和可达性分析。

引用计安全生产法数法

给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为索引页是哪一页 0 的对象就是不可能再被使用的。

这种方法很难解决对象之间相互循环引用的问题。比如下面的代码,obj1obj2 互相引用,这种情况下,引用计数器的值都是1,不会被垃圾回收。

public class ReferenceCount {
Object instance = null;
public static void main(String[] args) {
ReferenceCount obj1 = new ReferenceCount();
ReferenceCount obj2 = new ReferenceCount();
obj1.instance = obj2;
obj2.instance = obj1;
obj1 = null;
obj2 = null;
}
}

编解码器是什么意思达性分析

通过GC Root对象为起点,从这些节点向下搜索,搜索所走过的路径叫引用链,当一个对象到GC Root没有任何的引用链相连时,说明这个对象是不可用的。

大厂必问的JVM面试题

可作为GC Roots的对象有哪些安全教育平台登录入口

  1. 虚拟机栈中引用的对象
  2. 本地方法栈中Native方法引用的对象
  3. 方法区中存储过程类静态属性引用的对象
  4. 方法区中常量引用的对象

什么情况下类会被卸载?

需要同时满足以下ued2招商梁判官3o678 3 个条件类才可能会被卸载 :

  • 该类所有的实例都已经被回收。
  • 加载该类的类加载器已经被回收。
  • 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过索引是什么意思反射访问该类的方法。

虚拟机可以对满足上述 3 个条件的类进行回收,但不一定会进行回收。

强引用、软引用、弱引用、虚引用是什么,有什么区别?

强引用:在程序中普遍存在的引用赋值,类似Object obj = new Object()这种引用关系。只要强引用关系还存在,垃圾收集器就永远不会回收掉被ued设计引用的对象。

软引用:如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。

//软引用
SoftReference<String> softRef = new SoftReference<String>(str);

弱引用:在进行垃圾回收时,不管当前内存空间足够与否,都会回收只具有弱引用的对象。

//弱引用
WeakReference<String> weakRef = new WeakReference<String>(str);

虚引用:虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要是为了能在对象被收集器回收时收到一个系统通知

Minor GC 和 Full GC的区存储别?

  • Minor GC:回收新生代,因为新生代对象存活时间索引很短,因此 Minor GC会频繁执行,执行的安全速度一般也会比较快。
  • Full算法的五个特性 GC:回收老年代和新生代,老年代的对象存活时间长,因此 Full GC 很少执行,执行速度会比 Minor GC 慢很多。

内存的分配策略?

对象优先在 Eden 分配

大多数情况下,对象在新生代 Eden 上分配,当监控 Eden 空间不够时,触发 Minor GC

大对象直接进入老年代

大对象是指需要连续内存空间的对象,最存储处理国家秘密的计算机信息典型的大对象有长字符串和大编解码数组。可以设置JVM参数 -XX:PretenureSizeThreshold,大于此值的对象直接在老年代分配。

长期存活的对象进入老年代

通过参数 -XX:MaxTenuringThreshold 可以设置对象进入老年代的年龄阈值。存储器对象在Survivor区每经过一次 Minor GC,年龄就增加 1 岁,当它的年龄增加到一定程度,就会被晋升到老年代中。

动态对象年龄判定

并非对象的年龄必须达到 MaxTenuringThreshold 才能晋升老年代,如果在 Survivor 中相同年龄所有对象大小的总和大于 Survivor 空间的一半,则年龄大编解码不可用是什么意思于或等于该年龄的对象可算法的三种基本结构以直接进入老编译器是系统软件年代,无存储空间清理需达到 MaxTenuringThreshold 年龄阈值。

空间分配担保

在发生 Minor GC 之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果条件成立的话,那么 Minor GC 是安全的。如果不成立的话虚拟机会查看 HandlePromotionFailure 的值是否允许担保失败。如果允许,那么就会继续检查老年代最大可用的连续空间是否大于历次ued2注册问33300晋升到老年代对象的平均大小,如果大于,将尝试着进行一次 Minor GC;如果小于,或者 HandlePromotionFailure 的值为不允安全期计算器许担保失败,那么就要进行一次 Full GC

Full GC 的触发条件?

对于 Minor GC,其触发条件比较简单,当 Eden 空间满时,就将触发一次 Minor GC。而 Full GC 触发条件相对复杂,有以下情况会发生 full GC:

ued2招商找33300用 System.gc()

只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建ued2招商梁判官3o678议使用这种方式,而是让虚拟机管理内存。

老年代空间不足

老年代空间不足的常见场景为前文所缺少编解码讲的大对象直接进入老年代、长期存活的对象进入老年代等。为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。除此之外,可以通过 -Xmn 参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。

空间分配担保失存储空间清理

使用复制算法的 Minor GC 需索引页是哪一页要老年代的内算法是什么存空间作担保,如果担保失败会执行一次 Full GC。

JDK 1.7 及以前的永久代空间不足

在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。当系统中要加载的类、反射的类和调用的索引失效方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOfMemoryError。

垃圾回收算法有哪些?

垃圾回收算法有四种,分别是标记清监控app除法、标记整理法、复制算法、分代收集算法

标记清除算法

首先利用可达性去遍历内存,把存活对象和垃圾对象进行标记c#是什么语言。标记结束后统一将所有标记的c#和java对象回收掉。这种垃圾回收算法效率较低,并且会产生大量不连续的空间碎片存储器

大厂必问的JVM面试题

复制清除算法

半区复制,用于新生代垃圾回收。将内安全存分为大小相同的两块,每安全教育平台登录系统次使编解码器不可用是什么意思用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。

特点:实现简单,编译器是什么意思运行高效,但可用内存缩小为了原来的一半,浪费空间。

标记整理算法

根据老年代的特点提出的一种标记算法,标记过程仍然与标记编译器和解释器的区别-清除存储器算法一样,监控app但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以存储器可分为哪三类外的内存。

大厂必问的JVM面试题

分类收集算法

根据各个年代的特点采用最适当的收集算法。

一般将堆分为新生代和老年代。

  • 新生代使用复制算法
  • 老年代使编译器英文用标记清除算法或者标记整理算法

在新生代中,每次垃圾收集时都存储过程有大批对象死去,索引符号只有少量存活,安全教育平台使用复制算法比较合适,只需要付出少量存活对象的复制成本就可以完成收集。老年代对象存活率高,适合使用标记-清理或者标记-整理算法进行垃圾回收。

有哪安全教育平台登录系统些垃圾回收器?ued2娱乐问33300

垃圾回收器主要分为以下几种:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1

这7种垃圾收集器的特点:

收集器 串行、并java语言行or并发 新生代/老年代 算法 目标 适用场景
Serial 串行 新生代 复制算法 响应c#是什么语言速度优先 单CP索引图U环境下的Client模式
ParNew 并行 监控摄像头生代 复制算法 响应速度优先 多CPU环境时在Server模式下与CMS配合
P编译器和解释器的区别arallel Scaveng安全教育平台登录系统e 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
Serialjava编译器 Old 串行编译器原理 老年算法工程师 标记-整理 响应速度优先 单CPU环境下的Client模式、CMS的后备预案
Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 标记-清除 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用
G1 并发 bo算法设计与分析th 标记-整理+复制算法 响应速度优先 面向服务端应用,将来替换CMS

Serial 收集器

单线程收集器,使用一个垃圾收集线程去进行垃圾回收,在进行垃圾回收的时候必须暂停其他所有的工作线程( S编译器是系统软件top T监控系统he World ),直到它收集结束。

特点:简单高效;内存消耗小;没有线ued设计师是做什么的程交互的开销算法的时间复杂度是指什么,单线程收集安全教育效率高;需暂停所有的工作线程,用户体验不好。

ParNew 收集器

Serial收集器的多线程版本ued2平台问33300除了使用多线程进行垃圾收集外,其他行为、参数与 Serial 收集器基本一致。

Parallel Scavc#为什么用的人很少enge 收集器

新生代收集器,基于复制清除算法实现的收集器。特点是吞吐量优先,能够并行收集的多线程收集器,允许多个垃圾回收线程同时运行,降低垃圾收集时间,提高吞吐量。所谓吞吐量就是 C编译器PU 中用于运行用户代码的时间与 CPU 总消耗时间存储容量单位的比值(吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间))。Parallel Scavenge 收集器关注点是吞吐量,高效率的利用 CPUjava 资源CMS 垃圾收集器关注点更多的是用户线程的停顿时间

Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio参数。

  • -XX:MaxGCPauseMillis参数的值是一个大于0的毫秒数,收集器将尽量保证内存回收花费的时间不超过用户设定值。
  • -XX:GCc#为什么用的人很少TimeRatio参数的值大于索引金枝0小于100,即垃圾收集时间占总时间的比率,相当于吞吐量的倒数。

Serial Old 收集器

Serial 收集器的老年代版本,单线程收集器,使用标记整理算法

Parallel Old 收集器

Parallel Scavenge 收集器的老年代版本。多线程垃圾收集,使用标记整理算法

CMS 收集器

Concurrent Mark Sweep ,并发标记清除,追求获取最短停顿时间,实现了让垃圾收集线程与用户线程基本上同时工作

CMSjava模拟器圾回收基于标记清除算法实现,整个过程分为四个步骤:

  • 初始标记: 暂停所有ued2招商梁判官3o678用户线程(Stop The World),记录直接与 GC Roots 直接相连的对监控系统象 。
  • 并发标记:从GC Roots开始对存储容量堆中对象进行可达性分析,找出存活对监控象,耗时较长,但是不需要停顿用户线程。
  • 重新标记: 在并发标记期间对象的引用关系可能会变化,需要重新进行标记。此阶段也会暂停所有用户线程。
  • 并发清除:清除标记对象,这个阶段也是可以与用户线程同时并发的。

在整个过程中,耗时最长的是并发标记和并发清除阶段,这两个阶段垃圾收集线程都可以与用户线程一起工作,所以从总体上来说,CMS收集器的内存回收索引超出矩阵维度过程是与用户线程一起并发执行的。

优点:并发监控眼收集,停顿时间短。

缺点

  • 标记清除算法导致收集结束有大量空间碎片
  • 产生浮动垃圾,在并发算法分析的目的是清理阶段用户线程还在运行安全教育平台登录入口,会不断有新的垃圾产生,这一部分垃圾出现在标记过程之后,CMS无法在当次收集中回收它们,只好等到下一次垃圾回收再处理;

G1收集器

G1垃圾收集器的目标是在不同应用场景中追求高吞吐量和低停顿之间的最佳平衡

G1将整个堆分成相同大小的分区(Region),有四种不编译器英文同类型的分区:Eden、Survivor、Old和H编解码器不可用是什么意思umongous。分区的大小取值范围为 1M 到 32M,都是2的幂次方。分区大小可以通过-XX:G1HeapRegionSize参数指定。Humongousued2主管问33300区域用于存储大对象。G1规定只要大小超过了一个分区容量一半的对象就认为是大对象。

大厂必问的JVM面试题

G1 收集器对各个分区回收所获得的空间大小和回收所需时间的经验值进行排序,得到一个优先级列表,每次根据用户设置的最大回收停顿时间,优先回收价值最大的分区。

特点:可以由用户指定期望的垃圾编解码是什么意思收集停顿时间。

G安全教育平台学生账号登录入口1 收集器的回收过程分为以下几个步骤:

  • 初始标记。暂停所有其他线程,记录直接与 GC Roots 直接相连的对象,耗时较短 。
  • 并发标记。从GC Roots开始对堆中对象进行可达性分析,找出要回收的对象,耗时较长,不过可以和用户程序并发执行。
  • 最终标记。需对其他线程做短暂的暂停,用于处理并发标记阶段对象引用出现变动的区域。
  • 筛选回收。对各个分区的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,编译器然后把决定回收的分区的存活对象复制到空的安全教育平台学生账号登录入口分区中,再清理掉整个旧的分区的全部空间。监控app这里的操作涉及存活对象的移动,会暂停用户线程,由多条收集器编译器原理线程并行完成。

常用的 JVMjava编译器 调优的命令都有哪些?

jps:列出本机所有 Java 进程的进程号

常用参数如下:

  • -m 输出main方法的参数
  • -l 输出完全的包名和应用主类名
  • -v 输出JVM参数
jps -lvm
//output
//4124 com.zzx.Application -javaagent:E:\IDEA2019\lib\idea_rt.jar=10291:E:\IDEA2019\bin -Dfile.encoding=UTF-8

jstack:查看某个 Java 进程内的线程堆栈信息。使用参数-l可以打印额外的锁信息,发生死锁时可以使用jstack -l pid观察锁持有情况。

jstack -l 4124 | more

输出结果如下:

"http-nio-8001-exec-10" #40 daemon prio=5 os_prio=0 tid=0x000000002542f000 nid=0x4028 waiting on condition [0x000000002cc9e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x000000077420d7e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None

WAITING (parking)指线程处于挂起中,在等待某个条件发c#接口生,来把自己唤醒。

j存储容量单位stat:用于查看虚拟机各种运行状态信息(类装载、内存、垃圾收集等运行数据)。使用参数-gcuitl可以查看垃圾回收的统计信息。

jstat -gcutil 4124
S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
0.00   0.00  67.21  19.20  96.36  94.96     10    0.084     3    0.191    0.275

参数说明:

  • S0Survivor0区当前使用比例
  • S1存储器Survivor1区当前使用比例
  • EEden区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收javascript消耗时间
  • GCT:垃圾回收消耗总时间

jmap:查看堆内存快照。通过jmap命令可以获得运行中的堆内存的快照,从而可以对堆内存进行离线分析。

查询进程4124的堆内存快照,输出结果如下:

>jmap -heap 4124
Attaching to process ID 4124, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.221-b11
using thread-local object allocation.
Parallel GC with 6 thread(s)
Heap Configuration:
MinHeapFreeRatio         = 0
MaxHeapFreeRatio         = 100
MaxHeapSize              = 4238344192 (4042.0MB)
NewSize                  = 88604672 (84.5MB)
MaxNewSize               = 1412431872 (1347.0MB)
OldSize                  = 177733632 (169.5MB)
NewRatio                 = 2
SurvivorRatio            = 8
MetaspaceSize            = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize         = 17592186044415 MB
G1HeapRegionSize         = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 327155712 (312.0MB)
used     = 223702392 (213.33922576904297MB)
free     = 103453320 (98.66077423095703MB)
68.37795697725736% used
From Space:
capacity = 21495808 (20.5MB)
used     = 0 (0.0MB)
free     = 21495808 (20.5MB)
0.0% used
To Space:
capacity = 23068672 (22.0MB)
used     = 0 (0.0MB)
free     = 23068672 (22.0MB)
0.0% used
PS Old Generation
capacity = 217579520 (207.5MB)
used     = 41781472 (39.845916748046875MB)
free     = 175798048 (167.65408325195312MB)
19.20285144484187% used
27776 interned Strings occupying 3262336 bytes.

对象头了解吗?

Java 内存中的对象由以下三部分组成:对象头安全教育平台登录入口例数据对齐填充字节

而对象头由以下三部分组成:mark word指向类信息的指针数组长度(数组才有)。

mark word包含:对象的哈希码、分代年龄和锁标志位。

对象的实例数据就是 Java 对象的属性和值。

对齐填存储空间清理充字节:因为JVM要求对象占的内存大小是 8bit 的倍数,因此后面有几个字节用于把对象的大小补齐至 8bit 的倍数。

内存对齐的主要作用是:

  1. 平台原因:不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某算法的三种基本结构些特定类型的数据,否则抛出硬件异常。
  2. 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。
  3. main方法执行过程

    以下是示例代码:

    public class Application {
    public static void main(String[] args) {
    Person p = new Person("大彬");
    p.getName();
    }
    }
    class Person {
    public String name;
    public Person(String name) {
    this.name = name;
    }
    public String getName() {
    return this.name;
    }
    }

    执行main方法的过程如下:

    1. 编译Application.ja安全教育平台登录系统va后得到c#和java Application.class 后,执行这个class文件,系统会启动一个编解码是什么意思 JVM 进程,从类路径中找到一个名为 Application.class 的二ued2平台问33300进制文件,将 Appli算法设计与分析cation 类信息加载到运行时数据区的方法区编译器是什么意思内,这个过程叫做类的加载。
    2. JVM 找到 Application 的主程序入口,执行main方法。
    3. main方法的第一条语句为 Persjava模拟器on p = new Person(监控器什么牌子最好清晰度高"大监控系统彬") ,就是让 JVM 创建一个Person对象,但是这个时候方法区中是没有 Person 类的信息的,所以 JVM 马上加载 Person 类,把 Person 类的信息放到安全教育平台登录方法区中。
    4. 加载完 Person 类后,JVM 在堆中分配内存给 Person 对象,然后调用构造函数初始化 Person 对象,这个 Pe算法工程师rson 对象持有指向方法区中的 Person 类的类型信息的引用。
    5. 执行p.getName()时,JVM 根据 p 的引用找到 p 所指向的对象,然后根据此对象持有的引用定位到方法区中 Person 类的类型信息的方法表,获得 getName() 的字节码地址。
    6. 执行getName()方法。
  4. 对象创建过程

    1. 类加载检查:当虚拟机遇到一条 new 指令时,首先检查是否能在常量池中定位到这个编译器类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析索引类型和初始化过。如果没有,那先执行类加载。
    2. 分配内存:在类加载检监控摄像头查通过后算法,接下来虚拟机将为对象实例安全期计算器分配内存。
    3. 初始化。分配到的内存空间都初始化为零值,通过这个操作保证了对象的字段可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
    4. 设置对象头Hjavascriptotsp编解码器ot 虚拟机的对象头包括:存储对象自身的运行时数据(哈希码、分代年龄、锁标志等等)、类型指针和数据长度存储处理国家秘密的计算机信息(数组对象才有),类型指针就是对象指向它的类信息的指监控怎么查看回放针,虚存储容量拟机通过这个指针来确定这个对象是哪个类的实例。
    5. 按照Java编解码器是什么意思码进行初始化

如何排查 OOM 的问题?

排查 OOM 的方法:

  • 增加JVM参数 -XX:+HeapDumpOnOutOfMemoryError-XX:Heap安全教育平台登录系统DumpPath=/tmp/heapdump.hpr算法的时间复杂度是指什么of,当 OOM 发生时自动 dump 堆内存信息到指定目录;
  • jstat 查看监控 JVM 的内存和 GC 情况,评估问题大概出在什么区域;
  • 使用 MAT 工具载入 dum安全教育p 文件,分析大对象的占用情况 。

GC是什么?为什么要GC?

GC 是垃圾收算法的五个特性集的意思(Gabage Collection)。内安全教育平台官方网站存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序的不稳定甚至崩溃,Java 提供的 GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的。

参考资料

  • 周志明. 深入理解 Java 虚拟机 [M]. 机械工业出版社

本文目录:

  • 讲一下JVM内存结构?

    • 程序计数器
    • 虚拟机栈
    • 本地方法栈
    • 方法区
    • 运行时常量池
    • 直接内存
  • Java对象的定位方式
  • 说一下堆栈的区别?
  • 什么情况下会发编译器原理生栈溢出?
  • 类文件结构
  • 什么是类加载?类加载的过程?
  • 什么是双索引金枝亲委编译器派模型?
  • 为什么需要双亲委派模型?
  • 什么是类加载器,类加载器有哪些?
  • 类的实例化顺序?
  • 如何判断一个对象是否存活?
  • 可作为GC Roots的对象有哪些?
  • 什么情况下类会被卸载?
  • 强引用、软引用、弱引用、虚引用是什么,有什么区别?
  • Minor GC 和 Full GC的区别?
  • 内存的分配策略?
  • Full GC 的触发条件?
  • 垃圾回收算法有哪些?
  • 有哪些垃圾回收编译器器?
  • 常用的 JVM 调优的命令都有哪些?
  • 对象头了解吗?
  • 如何排查 OOM 的问题?
  • GC是什么?为什么要GC?

我将大厂常见的高频面试题整理成PDF了,存储方便大家阅读,需要的小伙伴可以自行下载(复制链接到浏览器打开):

链接:https://pan.baidu.com/s/16GnVoALA1rc#是什么6BhumuUrXIRg
提取码:6666

讲一下JVM内存结构?

JVM内存结构分为5大区域,程序计数器虚拟机栈本地方法栈方法区

大厂必问的JVM面试题

程序计数器

线程私有的,作监控怎么查看回放为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址。c#程序设计程序计数器主要有两个作用:

  1. 当前线程所执行的字节码的行号指示器,通过它实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
  2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,当线程被切换回来的时候能够知道它上次执行的位置。

程序计数器是唯一一个不会出ued2主管问33300OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的监控系统结束而死亡。

虚拟机栈

Jav安全期计算器a 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表操作数栈动态链接方法出口信息。每一次函数调用都会有一个对应的栈帧被压入虚拟机栈,每一个函数调用结束后,都会有一个栈帧被弹出。

局部变量表是用于存放方法参数和方法内的局部变量。

每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,在方法调用过程中,会进行UED动态链接,将这个符号引用转化为直接引用。

  • 部分符号UED引用在类加载阶段的时候就转索引失效化为直接引用,这种转化就是静态链接
  • 部分符号引用在运行期间转化为直接引用,这种转化就是动态链接

Java 虚拟机栈也是线程私ued2招商找33300有的,每个线程都有各自的 J编译器ava 虚拟机栈,而且随着线程的创建而创建,随着线程的死亡而死亡。Java 虚拟机栈编译器会出现两种错误:StackOverFlowEued2注册问33300rrorOutOfMemoryError

可以通过 -Xss 参数来指定每个线程的虚拟机栈内存大小:

java -Xss2M

本地方法栈

虚拟机栈为ued2招商找33300虚拟机执ued2注册问33300Java 方法服务,而本地方法栈则为虚拟机使用到的 Native 方法缺少编解码服务。Native 方法一般是用其它语言(C、C++等)编写的。

监控怎么查看回放地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。安全期计算器

堆用于存放对象实例,是垃圾收集器管理的主要区域,因此也被称作GC监控眼。堆可以细分为:新生代(Eden空间、From SurvivorTo Survivor空间)和老年代存储器

通过 -Xms设定存储程序启动时占用内存大小,通过javascript-Xmx设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出算法的有穷性是指索引超出了数组界限什么意思这个设置值,就会抛出OutOfMemory异常。

java -Xms1M -Xmx2M

方法区

方法区与 Java 堆算法的三种基本结构一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

对方法区进行垃圾回收的主要目标是对常量池的回收和对类的卸载

永久代

方法区是 JVM 的规范,而永久代PermGen是方法区的一种实现方式,并且只有 HotSpot 有永久代。对于其他类型的虚拟机,如JRockit存储处理国家秘密的计算机信息没有永久代。由于方法区安全教育平台主要存储类的相关信息编解码是什么意思,所以对于动态生成类的场景比较容易出现永久代的内存溢出。

元空间

JDK 1.8 的时候,HotSpot的永久代被彻底移除了,使用元空间替代。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。两者最大的区别在于:元空间并不在虚拟机中,而是使用直接内存。

为什么要将永久代替换为元空间呢?

永久代内存受限于 JVM 可用内存,而元空间使用索引失效的是直接内存,受本机可用内存的限制,虽然元空间仍旧可能溢出,但是相比永久代内存溢出的概率更小。

运行时常java培训量池

运行时常量池是方法区的一部分,在类加载之后,会将编译器生成的各种字面量和符号引号放到运行时常量池。在运行期间动态生成的常量,如 String 类的 intern()方法编解码,也会被放入运行时常量池。

大厂必问的JVM面试题

大厂必问的JVM面试题

大厂必问的JVM面试题

图片来源:https://blog.csdn.net/soonfly

直接内存

直接内存并不是虚拟机运行时数据区的一部分,也不是虚拟机规范中定义的内存区域,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMe存储器中存取速度最快的是moryError 错误出现。

N索引图IO的Buffer提供了DirectBu编译器下载ffer,可以直接访问系统物理内存,避免堆内内存到堆外内存的数据拷贝操作,提高效率。DirectBuffer直接分配在物理c#委托内存中,并算法分析的目的是不占用堆空间,其可申请的最大内存受操作系统限制,不受最大堆内存的限制。

直接内存的读写操作比堆内存快,可以提升程序I/O操作的编解码不可用是什么意思性能。通常在I/O通信过程中,会存在堆内索引是什么意思内存到堆外内存的数据拷贝操作,对于需要频繁进行内存间数据拷贝且生命周期较短的暂存数据,都建议存储到直接内存。

Java对象的定位方式

Java 程序通过栈上的 reference 数据来操作堆上的具体对象。对象的访问方式由虚拟机索引金枝实现而定,目前主流的访问方式有使用句柄和直接指针两种:

  • 如果使用句柄的话,那么 Java 堆中将会划分出一块内存来作为句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对算法工程师象实例数据与类型数据各自的具体地监控摄像头怎么连接手机址信息。使用句柄来访问的最大好处是算法的三种基本结构 reference 中存储的算法是稳定的句柄地址,在对象被移动时只会改变句柄中的c#委托实例数据指针,而 refereuedbetnce 本身不需要修UED改。
  • 直接指针。reference 中存储的直监控视频能保存多久接就是对象的地址。对象包含到对象类型数据的指针,通过这个指针可监控器什么牌子最好清晰度高以访算法导论问对象类型数据。使用直接指针访问方式最大的好处就是访问对象速度快,它节省了一次指针定位的时间开销,虚拟机hotspot主要是使用直接指针来访问对象。

说一下堆栈的区别?

  1. 堆的物理地址分配是不连续的,性能较慢;栈的物理地址分配是连续的,性能相对较快。
  2. 堆存放的是对象的实例和数组;栈存放的是局部变量,操作数栈,返回结果等。
  3. 堆是线程共享的;栈是java模拟器线程私有的。

什么情况下会发生栈溢出?

  • 当线程请求的栈深度超过了虚拟机允许的最大深度时,会抛出StackOverFlowError异常。这种情况通常是因为方法递归没终止条件。
  • 新建线程编解码器的时候没有足够的内存去创建对应的存储处理国家秘密的计算机信息虚拟机栈,虚拟机会抛出OutOfMemoryError异常。比如线程启动过多就会出现这种情况。

类文件结构

Class 文件结编解码器构如下:

ClassFile {
u4             magic; //类文件的标志
u2             minor_version;//小版本号
u2             major_version;//大版本号
u2             constant_pool_count;//常量池的数量
cp_info        constant_pool[constant_pool_count-1];//常量池
u2             access_flags;//类的访问标记
u2             this_class;//当前类的索引
u2             super_class;//父类
u2             interfaces_count;//接口
u2             interfaces[interfaces_count];//一个类可以实现多个接口
u2             fields_count;//字段属性
field_info     fields[fields_count];//一个类会可以有个字段
u2             methods_count;//方法数量
method_info    methods[methods_count];//一个类可以有个多个方法
u2             attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
}

主要参数如下:

魔数class文件标志。

文件版本:高版本的编解码器 Java 虚拟机可以执行低版本编译器生存储器中存取速度最快的是成的类文件,但是低版本的 Java 虚拟机不能执行高版本编译器生成的类文件。

常量池:存放字面量和符号引用。字面量类似于 Java 的常量,如字符串,声明为final的常量值等。符号引用包含三类:类和接口的算法的时间复杂度是指什么全限定名,方法的名称和描述符,字段的名称和描述符。

访问标志:识别类或者接口的访问信息,比如编译器下载这个Class是类还是接口,是否为 public 或者 abstra编译器ct 类型等等。

当前类的索引:类索引用于确定这监控个类的全限定名。

什么是类加载?类加载的过程?

类的加载指的是将类的class文件中的二进制数据读入到内存存储器可分为哪三类中,将其放在编解码是什么意思运行时数据区的编译器是系统软件吗方法区内,然后在堆区创建安全期计算器一个此类的对象,通过这个对象可以访问到方法区对应的类信息。

大厂必问的JVM面试题

加载

  1. 通过类的全限定名获取定义此类的二进制字存储过程节流
  2. 将字节流所代表的静态存储java面试题结构转换为方法区的运行时数据结构
  3. 在内存中生成一个代表该类的Class对象,作为方法区类信息的访问入口

验证

确保Class文件的字节流中包含的信息符合虚拟机规监控眼范,保证在运行后不会危害虚拟机自身的安全。主要包括四种验安全教育证:文件格式验证,元ued2注册问33300数据验证,字节码验证,符号引用验证

准备

为类变量分配内存并设置类变量初始值的阶段。

解析

虚拟机将常量池内的符号引用替换为直接引用的过程。java面试题符号引用用于描述目标,直接引用直接指向目标的地址。

初始化

开始执行类中定义的Java代码,初始化阶段是调用类构造器的过程。

什么是双亲委派模型?

一个类加载器收到一javascript百炼成仙个类的加载请求时,它首先不会自己尝试去加载它,而是把这个请求委派给父类加载器去完成,这样层层委派,因此所有的加载请求最终都会传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去加编译器是什么意思载。

大厂必问的JVM面试题

双亲委派模型的具体实现代码在 java.lang.ClassLoader中,此类的 loadClass() 方法运行过程如下:先检查类是ued2招商找33300否已经加载过,如果没索引类型有则让父类加载器去加载。当父类加载器加载失败时抛出 ClassNotFoundException,此时尝试自己去加载。源码如下:

public abstract class ClassLoader {
// The parent class loader for delegation
private final ClassLoader parent;
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
}

为什么需要双亲委派模型?

双亲委派模型的好处:可以防止内存中出现多份同样的字节码。如果没有双亲委派模型而是监控摄像头怎么连接手机由各个类加载器自行加载的话,如果用户编写了一个java算法设计与分析.编译器是怎么写出来的lang.Object的同名类并放在ClassPath中,多个类加载器都去加载这个类到内存中,系统中将会出现多个不同的Object类,那么类之间的比较结果及类的唯一性存储器将无法保证。

什么是类加载器,类加载器有哪些?

  • 实现编译器和解释器的区别通过类的全限定名获取该类的二进制字节流的代码块叫做类加载器。

    主要有一下四种类加载器:

    • 启动类加载器:用来加载 Java 核心类库,无法被 Java 程序直接监控引用。
    • 扩展类加载器:它用来加载 Java 的扩展库。算法的时间复杂度是指什么Jajavascript百炼成仙va 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
    • 系统类加载器:它根据应用的类路径来加载 Java 类。可监控眼通过ClassLoader.getS编译器作用ystemClassLoc#程序设计ader()获取它。
    • 自定义类加载器:通过继承java.安全教育平台登录lang.ClassLoader类的方式实现。

类的实例化顺序?

  1. 父类中的static代码块,当前类的static代码块
  2. 父类的普通代码块
  3. 父类的构造函数
  4. 当前类普通代码块
  5. 当前类的构造函数

如何判断一个对象是否存活?

对堆垃圾回存储单元收前的第一步就是要判断那些对象已经死亡(即不再被任何途径引用的对象)。判断对象是否存活有两种方法:引用计数法和可达性分析。

引用计数法

给对象中添加一c#教程个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象监控眼就是不可能再被使用的。

这种方法很难解决对象之间相互循环引用的算法的五个特性问题。比如下面的代码,obj1obj2 互相引用,这种编译器是首个中国公司开发出来的具有世界影响力的编译器情况下,引用计数器的值都是1,不会被垃圾回收。

public class ReferenceCount {
Object instance = null;
public static void main(String[] args) {
ReferenceCount obj1 = new ReferenceCount();
ReferenceCount obj2 = new ReferenceCount();
obj1.instance = obj2;
obj2.instance = obj1;
obj1 = null;
obj2 = null;
}
}

可达性分析

通过GC Root对象为起点,java编译器从这些节点向下搜索,搜索所走过的路径叫引用链,当一个对象到GC Root没有任何的引用链相连时,说明这个对象是不可用的。

大厂必问的JVM面试题

可作安全教育平台学生账号登录入口为GC Roots索引符号的对象有哪些?

  1. 虚拟机栈中引用的对象
  2. 本地方法栈中Native方法引用的对象
  3. 方法区中类静态属性引用的对象
  4. 方法区中常量引用的对象

什么情况下类会被卸载?

java培训要同时满足以下 3 个条件类才可能会被卸载 :

  • 该类所有的实例都已经被回收。
  • 加载该类的类加载器已经被回收。
  • 该类对应的监控app java.lang.Class 对象没有在任何索引超出了数组界限什么意思地方被引用,无监控app法在任何地方通过反射访问该类的方法。

虚拟机可以对满足上述 3 个条件的类进行回收,但不一定会进行回收。

强引用、软引用、弱引用、虚引用是什么,有什么区别?

强引用:在程序中普遍存在的引用赋值,类似Object obj = new Object()这种引用关系。只要强引用关系还存在,垃圾收集器就永远不会回收掉被引编译器是怎么写出来的用的对象。

软引用:如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。

//软引用
SoftReference<String> softRef = new SoftReference<String>(str);

弱引用:在进行垃圾回收时,不管当前内存空间足够与否,都会回收只具有弱引用的对象。

//弱引用
WeakReference<String> weakRef = new WeakReference<String>(str);

虚引用:虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要java培训是为了能在对象被收集器回收时收到一个系统通知

Minor GC 和 Full GC的区别?

  • Minor GC:回收新生代,因为新生代对象存活时间很短,因此 Minor GC会频繁执行,执行的速度一般也会比较快。
  • Full GC:回收老年代和新生代,老年代的对象存活时间长,因此 Full GC 很少执行,执行速度会比 Minor GC 慢很多。

内存的存储诸天分配策略?

对象优先在 Eden 分配

大多数情况下,对象在新生代 Eden 上分配,当 Eden 空间不够时,触发 Mjava面试题inor GC

大对象直接进入老年代

大对象是指需要连续内存空间的对象,最典型的大对象有长字符串和大数组。可以设置JVM参数 -XX:PretenureSizeThreshold,大于此值的对象直接在老年代分配。

长期存活的对象进入老年代

通过参数 -XX:MaxTenuringThreshold 可以设置对象进入老年代的年龄阈值。对象在c#面试题Survivor区每经过一次 Minor GC,年龄就增加 1 岁,当它的年龄增加到一定程度,就会被晋升到老年代中。

动态对象年龄判定

并非对象的年龄必须达到 MaxTenuringThresc#hold 才能晋升老年代,如果在 Survivor 中相同年龄所算法设计与分析有对象监控摄像头怎么连接手机大小的总和大于 Survivor 空间的一半,则年龄大于索引类型或等于该年龄的对象可以直接进入老年代,无需达到 MaxTenuringThreshold 年龄阈值。

空间分配担保

在发生 Minor GCc#前,虚拟机先检查编译器老年代最大可用的连续空间是否大于新生代所有对象总空间,如果条件成立的话,那么 Minor GC 是安全监控怎么查看回放的。如果不成立的话虚拟机会查看 HandlePromotionFailu安全教育平台登录re 的值是否允许担保失败。如果允许,那么就会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次 Minor GC;如果小于,或者 HandleProm编解码otionFailure 的值为不ued2招商梁判官3o678允许担保失败,那么就要进行一次 Full GC

Full GC 的触发条件?

对于 Minor GC,其触发条件比较简单,当 Eden 空间满时,就将触发一次 Minor GC。而 Full GC 触发条件相对复杂,有以下情况会发生 full GC:

调用 System.gc()

只是建议虚拟机执行 Full安全教育平台学生账号登录入口 GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。

老年代空间不足

老年代空间不足的常见场景UED为前文所讲的大对象直接进入老年代、长期存活的对象进入老年代等监控摄像头怎么连接手机。为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。编译器英文除此之外,可以通过 -Xmn 参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老安全教育平台官方网站年代。还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。

空间分配担保失败

使用复制算法的 Minor GC 需监控摄像头怎么连接手机要老年代的内存空间作担保,如果担保失败会执行安全教育平台登录系统一次 Full GC。

JDK 1.7 及以前的永久代空间不足

在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。当系统中要加载的类、反射的类和调用的方法较多时,永久代可能算法的三种基本结构会被占满,在未配置为采用 CMS GC 的情况下也会执行 Full GC。如果经过 Full GC 仍然回收不了,那么虚拟机会抛出 java.lang.OutOUEDfMemoryError。

垃圾回收存储单元算法有哪些?

垃圾回收算法有四种,分别是标记清除法、标记整理法、c#和java复制算法、分代收集算法

标记清除算法

首先利用可达性去编解码器是什么意思遍历内存,把存活对象ued2招商找33300和垃圾对象进行标记。标ued2招商找33300记结束后统一将所有标记的对象回收掉。这种垃圾回收算法效率较低,并且会产生大量不连续的空间碎片

大厂必问的JVM面试题

复制清除算法

半区复制,用于新生代垃圾回收。将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清算法的时间复杂度是指什么理掉。

特点:实现简单,运行高效,但可用内存缩小为了原来的一半,浪费空间。

标记整理算法

算法分析的目的是据老年代的特点提出安全教育平台登录系统的一种标记算法,标c#是什么语言记过程仍然与安全生产法标记-清除算法算法工程师一样,但后续步骤不是直接对可c#委托回收对象进行清理,而是让所有ued2注册问33300存活的对象都向一端移动,然后直接清理掉边界以外的内存。

大厂必问的JVM面试题

分类收集算法

根据各个年代的特ued设计点采用最适当的收集算法。

一般将堆分为新生代和老年代。

  • 新生代使用复制算法
  • 老年代使用标记清除算法或者标记整理算法

在新生代中,每次垃圾收集时都有大批对象死去,只有少量存活,使用复制算法比较合适,只需要付出少量存活对象的复制成本就可以完成收集。老年代对象存活率高,适合使用java语言标记-清理或者标记-整理算法进行垃圾回收。

有哪些垃圾回收器?

垃圾回收器主要分为以下几种:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1

这7种垃圾收集器的特点:

收集器 串行、并行or并发 新生代/老年代 算法 目标 适用场景
Se索引失效rial java怎么读 新生代 复制算法 java模拟器应速度优先 单CPU环境下的Client模式
ParNew 并行编译器原理 新生代 复制算编译器 响应速度优先 多CPU环境时在Server模式下与CMS配合
Parallel Scave索引符号表示的含义nge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
Serial Old ued2平台问33300 老年代 标记-整理 响应速度优先 单CPU环境下的Client模式、CMS的后备预案
Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 标记-清除ued2招商找33300 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用
G1 并发 b编译器英文oth 标记-整理+复制算法 响应速度优先 面向服务端应监控用,将来替换CMS

Serial 收集器

单线程收集器,使用一个垃圾收集线程去进行垃圾回算法的特征收,在进行垃圾回收的时候必须暂停其他所java有的工作线程( Stop The World ),直到它收集结束。

特点:简单高效;内存消耗小;没有线程交互的开销,单线程收集效率高;需暂停所有的工作线程,用户体验不好。

ParNew 收集器

Serial收集器的多线程版本,除了使用安全教育平台登录多线程进行垃圾收集外,其他行为、参数与 Serial 收集器基本一致。

Parallued2招商找33300el Scavenge 收集器

新生代收集器,基于复制算法的特征清除算法安全实现的收集器。特点是吞吐量优先,能够并行收集的多线程收集器,允许多个垃圾回收线程ued2主管找扣或徽22212同时运行,降低垃圾收集时间,提高吞吐量。所谓吞吐量就存储空间清理是 CPU 中用ued设计师是做什么的于运行用户代码的时间与 CPU 总消耗时间的比值(吞吐量 = 运行用户代码时存储诸天间 /(运行用户代码编译器是首个中国公司开发出来的具有世界影响力的编译器时间 + 垃圾收集时间))。Parallel Scavenge 收集器关注点是吞吐量,高效率的利用 CPU 资源CMS 垃圾收集器关注点更多的是用户线ued2招商找33300程的停顿时间

Parall索引图el S编译器下载cavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃c#委托圾收集停顿时间的-XX:Mued设计师是做什么的axGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRat算法是什么io参数。

  • -XX:MaxGCPausec#程序设计Millis参数的值是一个大于0的毫秒数,收集器将尽量保证内存回收花费的时间不超过用户设定值。
  • -XX:GCTimeRatio安全参数的值大于0小于100,即垃圾收集时间占总时uedbet间的比安全率,相当于吞吐量的ued设计师是做什么的倒数。

Serial Old 收集器

Serial 收集器的老年代版本,单线程收集器,使用标记整理安全教育算法

Parallel Old 收集器

Paral监控视频能保存多久lel Scavenge 收集器的老年代版本。算法设计与分析多线程ued2平台问33300垃圾收集,使用标记整理算法

CMS 收集器

Concurrent Mark Sweep ,并发标记清除,追求获取最短停顿时间,实现了让垃圾收集线程与用户线程基本上同时工作

CMS 垃圾回收索引超出了数组界限什么意思基于标记清除算法实现,整个过程分为四个步骤:

  • 初始标记: 暂停所有用户线程(Stop The Wor编解码ld),记录直接与 GC Roots 直接相连的对象 。
  • 并发标记:从GC Roots算法的时间复杂度是指什么开始对堆中对象进行可达监控性分析,找出存活对象安全教育平台,耗时较长,但是不需要停顿用户线程。
  • 重新标记: 在并发标记期间对象的引用关系可能会变化,需要重新进行标记。此阶段也会暂停所有存储单元用户线程。
  • 并发清除:清除标记对象,这个阶段也是可以与用户线程同时并发的。

在整个过程中,耗时安全教育平台登录系统最长的是并发标记和并发清除阶段,这两个阶段垃圾收集线程都可以与用户线程一起工作,所以从总体上来说,CMS收集器的内存回收安全过程是与用户线程一起并发执行的。

优点:并发收集,停顿时间短。

缺点

  • 标记清除算法导致收集结束有大量空间碎片
  • 产生浮动垃圾,在并发清理阶段用编译器下载户线程还在运行,会不断有新的垃圾产生,这一部分垃圾出现在标记过程之后,CMS无法算法设计与分析在当次收集中回收它们,只好等到下一次垃圾回收再处理;

G1收集器

G1垃圾收集器的目标是在不同应用场景中追求高吞吐量和低停顿之间的最佳平衡

G1将整个堆分成相同大小的分区(Region),有四种不同类型的分区:Eden、Sued2平台问33300urvivor、Old和Humongous。分区的大小取值范围为 1M 到 32M,都是2的幂次方。分区大小可以通过-XX:G1HeapRegionSize参数指定。Humon监控器什么牌子最好清晰度高gous区域用于存储大对象。G1规定只要大小超过了一个分区容量一半的对象就认为是大监控对象。

大厂必问的JVM面试题

G1 收集器对各个分区回收所获得的空间大小和回收所需时间的经验值进行排序,得到一个优先级列表,每次根据用户设置的最大回收停顿时间,优先存储回收价值最大的分区。

特点索引符号表示的含义:可以由用户指定期望的垃圾收集停顿时间。

G1 收集器的回收过程分为以下几个步骤:索引超出了数组界限什么意思

  • 初始标记。暂停所有其他线程,记录直接与 GC Roots 直接相连的对象,耗时较短 。
  • 并发标记。从GC Roojava培训ts开始对堆中对象进行可达性分析,找出要回收的对象,耗时较长,不过可以和用户程序并发执行。
  • 最终标记。需对其他线程做短暂的暂停算法的三种基本结构,用于处理并发标记阶编译器是怎么写出来的段对象引用javascript出现变动的区域。
  • 筛选回收。对各个分区的回收价值和成本进行排序,根据用户所期望的停顿时间ued2注册问33300来制定回收计划,然后把决定回收的分区的存活对象复制到空的分区中,再清理掉整个旧的分区的全部空间。这里的操作涉及存活对象的移动,会暂停用户线程,由多ued2娱乐问33300条收集器线程并行完成。

索引超出矩阵维度用的 JVM 调优的命令都有哪些?

jps:列出本机所有 Java 进程的进程号

常用参数如下:

  • -m 输出main方法的参数
  • -l 输出完全的包名和应用主编译器是怎么写出来的类名
  • -v 输出JVM参数
jps -lvm
//output
//4124 com.zzx.Application -javaagent:E:\IDEA2019\lib\idea_rt.jar=10291:E:\IDEA2019\bin -Dfile.encoding=UTF-8

jstack:查看java面试题某个 Java 进程内的线程堆栈信息。使用参数-l可以打印额外的锁信息,发生死锁时可以使用jstack -l pid观察锁持有情况。

jstack -l 4124 | more

输出结果如下:

"http-nio-8001-exec-10" #40 daemon prio=5 os_prio=0 tid=0x000000002542f000 nid=0x4028 waiting on condition [0x000000002cc9e000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x000000077420d7e8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:103)
at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:31)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None

WAITING (parking)指线程处于挂起中,在等待某个条件发存储过程生,来把自己唤醒。

jstat:用于查看虚拟机各种运行状态信息(类缺少编解码装载、内存、垃圾收集等运行数据)监控怎么安装。使用参数-gcuitl可以查看垃圾回收的索引失效统计信息。

jstat -gcutil 4124
S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
0.00   0.00  67.21  19.20  96.36  94.96     10    0.084     3    0.191    0.275

参数说明:

  • S0S编译器urvivor0区当前使用比例
  • S1Survivor1区当前使用比例
  • EEden区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC存储容量老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃索引失效圾回收消耗总时间

jmap:查看堆内存快照。通过jm安全期计算器ap命令可以获得运行中的堆内存的快照,从而可以对堆内存进行离线分析。

查询进程4124的堆内存快照,输出结果如下:

>jmap -heap 4124
Attaching to process ID 4124, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.221-b11
using thread-local object allocation.
Parallel GC with 6 thread(s)
Heap Configuration:
MinHeapFreeRatio         = 0
MaxHeapFreeRatio         = 100
MaxHeapSize              = 4238344192 (4042.0MB)
NewSize                  = 88604672 (84.5MB)
MaxNewSize               = 1412431872 (1347.0MB)
OldSize                  = 177733632 (169.5MB)
NewRatio                 = 2
SurvivorRatio            = 8
MetaspaceSize            = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize         = 17592186044415 MB
G1HeapRegionSize         = 0 (0.0MB)
Heap Usage:
PS Young Generation
Eden Space:
capacity = 327155712 (312.0MB)
used     = 223702392 (213.33922576904297MB)
free     = 103453320 (98.66077423095703MB)
68.37795697725736% used
From Space:
capacity = 21495808 (20.5MB)
used     = 0 (0.0MB)
free     = 21495808 (20.5MB)
0.0% used
To Space:
capacity = 23068672 (22.0MB)
used     = 0 (0.0MB)
free     = 23068672 (22.0MB)
0.0% used
PS Old Generation
capacity = 217579520 (207.5MB)
used     = 41781472 (39.845916748046875MB)
free     = 175798048 (167.65408325195312MB)
19.20285144484187% used
27776 interned Strings occupying 3262336 bytes.

对象头了编译器下载解吗?

Java 内存中的对监控系统象由以下三部分组成:对象头实例数据对齐填充字节

而对象头由以下三部分组成:mark word指向类信息的java语言指针数组长度(数组才有)。

mark word包含:对象的存储容量哈希码、分代年龄和锁标志位。

对象的实例数据就是 Java 对象的属性和值。

对齐填充c#教程字节:因为JVM要求对象占的内存大小是 8bit 的倍数,因此后面有几个字java编译器节用于把对象的大小补齐至 8bit 的倍数。

内存对齐的主要作用是:

  1. 平台原因:不是所有的硬安全生产法件平台都能访问任意地址上的任意数据的安全教育平台官方网站;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
  2. 性能原因:经c#接口过内存对齐后,CPU的内存访问速度大大提升。
  3. main方法安全教育执行过程

    以下是示例代码:

    public class Application {
    public static void main(String[] args) {
    Person p = new Person("大彬");
    p.getName();
    }
    }
    class Person {
    public String name;
    public Person(String name) {
    this.name = name;
    }
    public String getName() {
    return this.name;
    }
    }

    执行main方法的过程如下:

    1. 编译Application.java后得到 Application.安全class 后,执行这个cla编解码器ss文件,系统会启动一个 JVM 进程,从类路径中找到一个名为 Application.索引页是哪一页class 的二进制文件,将 Application 类信息加载到运行时存储处理国家秘密的计算机信息数据区的方法区内,这个过程叫做类的加载。
    2. JVM 找到 Application 的主程序入口,执行main方法。
    3. main方法的第一条语句为 Person p = new Person("大彬") ,就是让 JVM 创建一个Person对象,但是这个时候方法区中是没有 Person 类的信息的,所ued2注册问33300以 JVM 马上加载 Person 类,把 Person 类的信息放到方法区中。
    4. 加载完 Person 类后,JVM 在堆中分配内存给 Person 对象,然后调用构造函数初始化 Person 对象,这个 Person 对象持有指向方法区中的 Person 类的类型信息索引页是哪一页引用。
    5. 执行p.getName()时,JVM 根据 p 的引用找到 p 所指c#向的对象,然后根据此对象持有的引用定位到方法区中 Person 类的类型信息的方法表,获得 getN安全教育平台a监控摄像头怎么连接手机me() 的字节码地址。
    6. 执行getName()方法。
  4. 对象创建过程

    1. 类加载检查:当虚拟机遇到一条 new 指令时,首先检查是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化过。如果没有,那先执行类加载。
    2. 分配内存:在类加载检查通过后,接下来虚拟机将为对象实例分配内存。
    3. 初始化。分配到的内存空间都初始化为零值,通过这个操作保证了对象的字段可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
    4. 设置对象头Hotspoued2注册问33300t 虚拟机的对象头包括:存储对象自身的运行时数据(哈希码、分代年龄、锁标志等等)、类型指针和数据长度(数组c#怎么读对象才有),类型指针就是对象指向它的类信息的指针,虚拟机通过这个指java面试题针来确定这个对象是哪个类的实例。
    5. 按照Java安全生产法代码进行初始化

如何java怎么读排查 OOM 的问题?

排查索引超出矩阵维度 OOM 的方法:

  • 增加JVM参数 -XX:+HeapDumpOnOutOfMemoryError-java模拟器XX:Heapjavascript百炼成仙DumpPath=/tmp/heapdump.hprof,当 OOM 发生时自动 du存储容量单位mp 堆内存信息到指定目录;
  • jstat 查看监控 JVM 的内存和 GC 情况,评估问题大概出在什么区域;
  • 使用 MAT 工具载入 dump 文件,分析大对象的存储容量单位占用情况 。

GC是什么?为什么要GC?

GC 是垃圾收集的意思(Gued2主管找扣或徽22212abage Collection)。内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序的不稳定甚至崩溃,Java 提供的 GC 功能可以自动监安全教育测对象是否超过作用域从而达到自动回收内存的目的。

参考资料

  • 周志明. 深入理解 Java 虚拟机 [M]. 机械工业出版社

文章对你有用的话,点个赞,支持一下~

我是大彬,非科班转码,校招拿了多家互联网中大厂offer,专注分享Java技术干货,欢迎关注~