JVM严镇涛版笔记【B站面试题】

前言

2023-06-19 18:49:33
出自B站 灰灰的Java面试

枫叶云链接:http://cloud.fynote.com/s/4976

JVM面试题大全 Lecturer :严镇涛

1.为什么需要JVM,不要JVM可以吗?

1.JVM可以帮助我们屏蔽底层的操作系统 一次编译,到处运行

2.JVM可以运行Class文件

image.png

2.JDK,JRE以及JVM的关系

03.png

3.我们的编译器到底干了什么事?

仅仅是将我们的 .java 文件转换成了 .class 文件,实际上就是文件格式的转换,对等信息转换。

image.png

4.类加载机制

image.png

类加载机制其实就是虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成可以虚拟机直接使用的Java类型,即java.lang.Class。

1.装载

Class文件 – >二进制字节流 -->类加载器

1)通过一个类的全限定名获取这个类的二进制字节流

2)将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构

3)在java堆中生成一个代表这个类的java.lang.Class对象,做为我们方法区的数据访问入口

2.链接:

1)验证:保证我们加载的类的正确性

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证

2)准备

为类的静态变量分配内存,并将其初始化为当前类型的默认值。

private static int a = 1 ; 那么他在准备这个阶段 a = 0;

3)解析

解析是从运行时常量池中的符号引用动态确定具体值的过程。

把类中的符号引用转换成直接引用

3.初始化

执行到Clinit方法,为静态变量赋值,初始化静态代码块,初始化当前类的父类

5.类加载器的层次

image.png

6.双亲委派机制

父类委托机制

源码 String 自己写 String

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) {
                long t0 = System.nanoTime();
                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.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }

image.png

7.如何打破双亲委派

1.复写

2.SPI Service Provider Interface 服务提供接口 日志 Xml解析 JBDC

可拔插设计 可以随时替换实现

3.OSGI 热部署 热更新
16461374670483013008ffy

8.运行时数据区

20.png

16461374670483019699ffy1.方法区 线程共享 方法区是逻辑上堆的一部分 所以他有个名字:非堆

运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化和接口初始化中使用 的特殊方法

如果方法区域中的内存无法满足分配请求,Java 虚拟机将抛出一个 OutOfMemoryError

2.堆 线程共享 堆是为所有类实例和数组分配内存的运行时数据区域 内存不足 OutOfMemoryError

3.java虚拟机栈 执行java方法的 线程私有的 StackOverflowError

4.本地方法栈 执行本地方法 线程私有 StackOverflowError

5.程序计数器 记录程序执行到的位置 线程私有

9.栈帧结构是什么样子的?

15.png

附加信息:栈帧的高度,虚拟机版本信息

栈帧信息:附加信息+动态链接+方法的返回地址

局部变量表:方法中定义的局部变量以及方法的参数都会存放在这张表中 ,单纯的存储单元

操作数栈 以压栈以及出栈的方式存储操作数

举例:

int a = 1;

int b = 1;

int c = a + b ;

方法的返回地址:当你一个方法执行的时候,只有两种方式可以推出

1.遇到方法的返回的字节码指令

2.出现了异常,有异常处理器,则交给异常处理器 ,没有呢?抛异常

10.动态链接

动态链接是为了支持方法的动态调用过程 。

动态链接将这些符号方法引用转换为具体的方法引用

符号引用转变为直接引用 为了支持java的多态

void a(){

b();

}

void b(){

c();

}

void c(){

}

11.java堆为什么要进行分代设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uMBO7nGP-1687171635915)(file:///C:\Users\root\AppData\Local\Temp\ksohtml\wpsE144.tmp.jpg)]22.png

新老年代划分

16461374670483019381ffy

Eden区与S区

12.[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NYW5rLRd-1687171635917)(file:///C:\Users\root\AppData\Local\Temp\ksohtml\wps7F2D.tmp.jpg)]老年代的担保机制

13.为什么Eden:S0:S1 是8:1:1[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s7CYE1t9-1687171635918)(file:///C:\Users\root\AppData\Local\Temp\ksohtml\wps942D.tmp.jpg)]

98%的对象朝生夕死

14.对象的创建过程

23.png

15.方法区与元数据区以及持久代到底是什么关系

方法区 JVM规范

落地:JDK1.7之前 持久代 Perm Space JVM虚拟机自己的内存

JDK1.8之后 元数据区 / 元空间 MetaSpace 直接内存

16461374670483013249ffy

16.什么时候才会进行垃圾回收

GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。
当然,我们可以手动进行垃圾回收,比如调用System.gc()方法通知JVM进行一次垃圾回收,但是
具体什么时刻运行也无法控制。也就是说System.gc()只是通知要回收,什么时候回收由JVM决
定。但是不建议手动调用该方法,因为GC消耗的资源比较大

(1)当Eden区或者S区不够用了
(2)老年代空间不够用了
(3)方法区空间不够用了
(4)System.gc()     //通知      时机也不确定      执行的Full  GC

17. 如何确定一个对象是垃圾?

要想进行垃圾回收,得先知道什么样的对象是垃圾。

  • 引用计数法

对于某个对象而言,只要应用程序中持有该对象的引用,就说明该对象不是垃圾,如果一个对象没有任何指针对其引用,它就是垃圾。

弊端:如果AB相互持有引用,导致永远不能被回收。 循环引用 内存泄露 -->内存溢出

16461374670483019208ffy

  • 可达性分析/根搜索算法

通过GC Root的对象,开始向下寻找,看某个对象是否可达

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oee0Mcut-1687171635921)(file://E:/%E6%A1%8C%E9%9D%A2/yzt/%E7%AC%94%E8%AE%B0%E8%AF%BE%E4%BB%B6/JVM/3%E5%A4%A9JVM%E8%AE%AD%E7%BB%83%E8%90%A5/%E8%B5%84%E6%96%99+%E7%AC%94%E8%AE%B0/images/64.png?lastModify=1646659177)]image.png

能作为GC Root:类加载器、Thread、虚拟机栈的本地变量表、static成员、常量引用、本地方法栈的变量等。

虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI(即一般说的Native方法)引用的对象。

18.对象被判定为不可达对象之后就“死”了吗

image.png

垃圾收集算法

已经能够确定一个对象为垃圾之后,接下来要考虑的就是回收,怎么回收呢?得要有对应的算法,下面介绍常见的垃圾回收算法。高效 健壮

标记-清除(Mark-Sweep)
  • 标记

找出内存中需要回收的对象,并且把它们标记出来

此时堆中所有的对象都会被扫描一遍,从而才能确定需要回收的对象,比较耗时

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IuL0BB27-1687171635922)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\25.png?lastModify=1646720640)]image.png

  • 清除

清除掉被标记需要回收的对象,释放出对应的内存空间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-roEivuWw-1687171635924)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\26.png?lastModify=1646720640)]image.png

缺点

标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程
序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
(1)标记和清除两个过程都比较耗时,效率不高
(2)会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
标记-复制(Mark-Copying)

将内存划分为两块相等的区域,每次只使用其中一块,如下图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pyg6A15O-1687171635925)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\27.png?lastModify=1646720640)]image.png

当其中一块内存使用完了,就将还存活的对象复制到另外一块上面,然后把已经使用过的内存空间一次清除掉。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LTJ91xFA-1687171635926)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\28.png?lastModify=1646720640)]image.png

缺点:空间利用率降低。

标记-整理(Mark-Compact)

复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都有100%存活的极端情况,所以老年代一般不能直接选用这种算法。

标记过程仍然与"标记-清除"算法一样,但是后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

其实上述过程相对"复制算法"来讲,少了一个"保留区"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tnNGnHQX-1687171635928)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\25.png?lastModify=1646720640)]image.png

让所有存活的对象都向一端移动,清理掉边界意外的内存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UVCyLkZr-1687171635929)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\29.png?lastModify=1646720640)]image.png

分代收集算法

既然上面介绍了3中垃圾收集算法,那么在堆内存中到底用哪一个呢?

Young区:复制算法(对象在被分配之后,可能生命周期比较短,Young区复制效率比较高)

Old区:标记清除或标记整理(Old区对象存活时间比较长,复制来复制去没必要,不如做个标记再清理)

垃圾收集器

如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UaJ6u0MM-1687171635931)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\30.png?lastModify=1646736013)]image.png

  • Serial

Serial收集器是最基本、发展历史最悠久的收集器,曾经(在JDK1.3.1之前)是虚拟机新生代收集的唯一选择。

它是一种单线程收集器,不仅仅意味着它只会使用一个CPU或者一条收集线程去完成垃圾收集工作,更重要的是其在进行垃圾收集的时候需要暂停其他线程。

优点:简单高效,拥有很高的单线程收集效率
缺点:收集过程需要暂停所有线程
算法:复制算法
适用范围:新生代
应用:Client模式下的默认新生代收集器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2RFO6GgQ-1687171635932)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\31.png?lastModify=1646736013)]image.png

  • Serial Old

Serial Old收集器是Serial收集器的老年代版本,也是一个单线程收集器,不同的是采用"标记-整理算法",运行过程和Serial收集器一样。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-grvtJfYu-1687171635934)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\32.png?lastModify=1646736013)]image.png

  • ParNew

可以把这个收集器理解为Serial收集器的多线程版本。

优点:在多CPU时,比Serial效率高。
缺点:收集过程暂停所有应用程序线程,单CPU时比Serial效率差。
算法:复制算法
适用范围:新生代
应用:运行在Server模式下的虚拟机中首选的新生代收集器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBlAzkgL-1687171635935)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\33.png?lastModify=1646736013)]image.png

  • Parallel Scavenge

Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器,看上去和ParNew一样,但是Parallel Scanvenge更关注系统的吞吐量

吞吐量=运行用户代码的时间/(运行用户代码的时间+垃圾收集时间)

比如虚拟机总共运行了100分钟,垃圾收集时间用了1分钟,吞吐量=(100-1)/100=99%。

若吞吐量越大,意味着垃圾收集的时间越短,则用户代码可以充分利用CPU资源,尽快完成程序的运算任务。

-XX:MaxGCPauseMillis控制最大的垃圾收集停顿时间,
-XX:GCRatio直接设置吞吐量的大小。
  • Parallel Old

Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多线程和标记-整理算法进行垃圾回收,也是更加关注系统的吞吐量

  • CMS

官网: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html#concurrent_mark_sweep_cms_collector

CMS(Concurrent Mark Sweep)收集器是一种以获取 最短回收停顿时间为目标的收集器。

采用的是"标记-清除算法",整个过程分为4步

(1)初始标记 CMS initial mark     标记GC Roots直接关联对象,不用Tracing,速度很快
(2)并发标记 CMS concurrent mark  进行GC Roots Tracing
(3)重新标记 CMS remark           修改并发标记因用户程序变动的内容
(4)并发清除 CMS concurrent sweep 清除不可达对象回收空间,同时有新垃圾产生,留着下次清理称为浮动垃圾

由于整个过程中,并发标记和并发清除,收集器线程可以与用户线程一起工作,所以总体上来说,CMS收集器的内存回收过程是与用户线程一起并发地执行的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JNAs0so6-1687171635936)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\34.png?lastModify=1646736013)]image.png

优点:并发收集、低停顿
缺点:产生大量空间碎片、并发阶段会降低吞吐量
  • G1(Garbage-First)

官网: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc.html#garbage_first_garbage_collection

**使用G1收集器时,Java堆的内存布局与就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。 **

每个Region大小都是一样的,可以是1M到32M之间的数值,但是必须保证是2的n次幂

如果对象太大,一个Region放不下[超过Region大小的50%],那么就会直接放到H中

设置Region大小:-XX:G1HeapRegionSize=M

所谓Garbage-Frist,其实就是优先回收垃圾最多的Region区域

(1)分代收集(仍然保留了分代的概念)
(2)空间整合(整体上属于“标记-整理”算法,不会导致空间碎片)
(3)可预测的停顿(比CMS更先进的地方在于能让使用者明确指定一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6wS8vB9c-1687171635937)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\35.png?lastModify=1646736013)]image.png

工作过程可以分为如下几步

初始标记(Initial Marking)      标记以下GC Roots能够关联的对象,并且修改TAMS的值,需要暂停用户线程
并发标记(Concurrent Marking)   从GC Roots进行可达性分析,找出存活的对象,与用户线程并发执行
最终标记(Final Marking)        修正在并发标记阶段因为用户程序的并发执行导致变动的数据,需暂停用户线程
筛选回收(Live Data Counting and Evacuation) 对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间制定回收计划

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FxjE87pX-1687171635938)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\36.png?lastModify=1646736013)]image.png

  • ZGC

官网: https://docs.oracle.com/en/java/javase/11/gctuning/z-garbage-collector1.html#GUID-A5A42691-095E-47BA-B6DC-FB4E5FAA43D0

JDK11新引入的ZGC收集器,不管是物理上还是逻辑上,ZGC中已经不存在新老年代的概念了

会分为一个个page,当进行GC操作时会对page进行压缩,因此没有碎片问题

只能在64位的linux上使用,目前用得还比较少

(1)可以达到10ms以内的停顿时间要求

(2)支持TB级别的内存

(3)堆内存变大后停顿时间还是在10ms以内

垃圾收集器分类

  • 串行收集器->Serial和Serial Old

只能有一个垃圾回收线程执行,用户线程暂停。

适用于内存比较小的嵌入式设备

  • 并行收集器[吞吐量优先]->Parallel Scanvenge、Parallel Old、ParNeww

多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

适用于科学计算、后台处理等若交互场景

  • 并发收集器[停顿时间优先]->CMS、G1、ZGC

用户线程和垃圾收集线程同时执行(但并不一定是并行的,可能是交替执行的),垃圾收集线程在执行的时候不会停顿用户线程的运行。

适用于相对时间有要求的场景,比如Web

吞吐量和停顿时间

  • **停顿时间->垃圾收集器 **进行 垃圾回收终端应用执行响应的时间
  • 吞吐量->运行用户代码时间/(运行用户代码时间+垃圾收集时间)
停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验;
高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任务。

小结:这两个指标也是评价垃圾回收器好处的标准。

生产环境中,如何选择合适的垃圾收集器

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html#sthref28

  • 优先调整堆的大小让服务器自己来选择
  • 如果内存小于100M,使用串行收集器
  • 如果是单核,并且没有停顿时间要求,使用串行或JVM自己选
  • 如果允许停顿时间超过1秒,选择并行或JVM自己选
  • 如果响应时间最重要,并且不能超过1秒,使用并发收集器

如何判断是否使用G1垃圾收集器

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases

JDK 7开始使用,JDK 8非常成熟,JDK 9默认的垃圾收集器,适用于新老生代。

是否使用G1收集器?

(1)50%以上的堆被存活对象占用
(2)对象分配和晋升的速度变化非常大
(3)垃圾回收时间比较长

JVM常用命令

  • jps

查看java进程

The jps command lists the instrumented Java HotSpot VMs on the target system. The command is limited to reporting information on JVMs for which it has the access permissions.
  • jinfo

(1)实时查看和调整JVM配置参数

The jinfo command prints Java configuration information for a specified Java process or core file or a remote debug server. The configuration information includes Java system properties and Java Virtual Machine (JVM) command-line flags.

(2)查看用法

jinfo -flag name PID 查看某个java进程的name属性的值

jinfo -flag MaxHeapSize PID 
jinfo -flag UseG1GC PID

3)修改

参数只有被标记为manageable的flags可以被实时修改

jinfo -flag [+|-] PID
jinfo -flag <name>=<value> PID

(4)查看曾经赋过值的一些参数

jinfo -flags PID
  • jstat

(1)查看虚拟机性能统计信息

The jstat command displays performance statistics for an instrumented Java HotSpot VM. The target JVM is identified by its virtual machine identifier, or vmid option.

(2)查看类装载信息

jstat -class PID 1000 10   查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次

(3)查看垃圾收集信息

jstat -gc PID 1000 10
  • jstack

(1)查看线程堆栈信息

The jstack command prints Java stack traces of Java threads for a specified Java process, core file, or remote debug server.

(2)用法

jstack PID

JVM死锁情况分析

//运行主类
public class DeadLockDemo
{
    public static void main(String[] args)
    {
        DeadLock d1=new DeadLock(true);
        DeadLock d2=new DeadLock(false);
        Thread t1=new Thread(d1);
        Thread t2=new Thread(d2);
        t1.start();
        t2.start();
    }
}
//定义锁对象
class MyLock{
    public static Object obj1=new Object();
    public static Object obj2=new Object();
}
//死锁代码
class DeadLock implements Runnable{
    private boolean flag;
    DeadLock(boolean flag){
        this.flag=flag;
    }
    public void run() {
        if(flag) {
            while(true) {
                synchronized(MyLock.obj1) {
                    System.out.println(Thread.currentThread().getName()+"----if获得obj1锁");
                    synchronized(MyLock.obj2) {
                        System.out.println(Thread.currentThread().getName()+"----if获得obj2锁");
                    }
                }
            }
        }
        else {
            while(true){
                synchronized(MyLock.obj2) {
                    System.out.println(Thread.currentThread().getName()+"----否则获得obj2锁");
                    synchronized(MyLock.obj1) {
                        System.out.println(Thread.currentThread().getName()+"----否则获得obj1锁");

                    }
                }
            }
        }
    }
}
  • jmap

(1)生成堆转储快照

The jmap command prints shared object memory maps or heap memory details of a specified process, core file, or remote debug server.

(2)打印出堆内存相关信息

jmap -heap PID
jinfo -flag UsePSAdaptiveSurvivorSizePolicy 35352
-XX:SurvivorRatio=8

G1调优策略

(1)不要手动设置新生代和老年代的大小,只要设置整个堆的大小

why:https://blogs.oracle.com/poonam/increased-heap-usage-with-g1-gc

G1收集器在运行过程中,会自己调整新生代和老年代的大小
其实是通过adapt代的大小来调整对象晋升的速度和年龄,从而达到为收集器设置的暂停时间目标
如果手动设置了大小就意味着放弃了G1的自动调优

(2)不断调优暂停时间目标

一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置成50ms就不太合理。暂停时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续的过程,逐步调整到最佳状态。暂停时间只是一个目标,并不能总是得到满足。

(3)使用-XX:ConcGCThreads=n来增加标记线程的数量

IHOP如果阀值设置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果阀值设置过低,就会使标记周期运行过于频繁,并且有可能混合收集期回收不到空间。 
IHOP值如果设置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高ConcGCThreads。

**(4)MixedGC调优 **

-XX:InitiatingHeapOccupancyPercent
-XX:G1MixedGCLiveThresholdPercent
-XX:G1MixedGCCountTarger
-XX:G1OldCSetRegionThresholdPercent

(5)适当增加堆内存大小

(6)不正常的Full GC

有时候会发现系统刚刚启动的时候,就会发生一次Full GC,但是老年代空间比较充足,一般是由Metaspace区域引起的。可以通过MetaspaceSize适当增加其大家,比如256M。

JVM性能优化指南

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8aDDSsGH-1687171635940)(file://E:\桌面\yzt\笔记课件\JVM\3天JVM训练营\资料+笔记\images\60.png?lastModify=1646833365)]image.png

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

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

相关文章

Windows安全应急--应急排查的一些方法

前言&#xff1a; 非法BC植入网站安全应急&#xff0c; 在安全应急中&#xff0c; 总会需要大大小小的问题&#xff0c; 就像成长一样。 检测工具尽量使用轻量级的。。 本次演示环境 Windows Server 2008 问题排查步骤&#xff1a; 先判断服务器有没有被Rootkit 查看登录…

[STM32-HAL库]Flash库-HAL库-复杂数据读写-STM32CUBEMX开发-HAL库开发系列-主控STM32F103C6T6

目录 一、前言 二、实现步骤 1.STM32CUBEMX配置 2.导入Flash库 3.分析地址范围 4.找到可用的地址 5.写入读取普通数据 6.写入读取字符串 6.1 存储相关信息 6.2 存取多个参数 三、总结及源码 一、前言 在面对需要持久化存储的数据时&#xff0c;除了挂载TF卡&#xff0c;我们…

java技术:oauth2协议

目录 一、黑马程序员Java进阶教程快速入门Spring Security OAuth2.0认证授权详解 1、oauth服务 WebSecurityConfig TokenConfig AuthorizationServer 改写密码校验逻辑实现类 2、oauth2支持的四种方式&#xff1a; 3、oauth2授权 ResouceServerConfig TokenConfig 4、…

CSS学习笔记之高级教程(二)

10、CSS 3D 转换 通过 CSS transform 属性&#xff0c;您可以使用以下 3D 转换方法&#xff1a; rotateX()rotateY()rotateZ() 10.1 rotateX() 方法&#xff08;使元素绕其 X 轴旋转给定角度&#xff09; <!DOCTYPE html> <html lang"en"><head&g…

2024-05-23 vscode + clang + clangd 解锁 modules

点击 <C 语言编程核心突破> 快速C语言入门 vscode clang clangd 解锁 modules 前言一、准备二、使用备注: 总结 前言 要解决问题: 昨天解锁VS使用modules, 但是不完美, 没有代码提示和补全了, 今天用 vscode clang clangd 解锁 modules, 同时还有代码补全及提示. …

第十一章 文件及IO操作

第十一章 文件及IO操作 文件的概述及基本操作步骤 文件&#xff1a; 存储在计算机的存储设备中的一组数据序列就是文件不同类型的文件通过后缀名进行区分 文本文件&#xff1a;由于编码格式的不同&#xff0c;所占磁盘空间的字节数不同(例如GBK编码格式中一个中文字符占2字…

K8S集群再搭建

前述&#xff1a;总体是非常简单的&#xff0c;就是过程繁琐&#xff0c;不过都是些重复的操作 master成员: [controller-manager, scheduler, api-server, etcd, proxy,kubelet] node成员: [kubelet, proxy] master要修改的配置文件有 1. vi /etc/etcd/etcd.conf # 数…

【设计模式深度剖析】【4】【创建型】【建造者模式】| 类比选购汽车的过程,加深理解

&#x1f448;️上一篇:抽象工厂模式 | 下一篇:原型模式&#x1f449;️ 目录 建造者模式概览定义英文原话直译如何理解呢&#xff1f;建造者模式将对象的建造过程给抽象出来了类比选购汽车 4个角色UML类图1. 抽象建造者&#xff08;Builder&#xff09;角色2. 具体建造者…

盲人社会适应性训练:打开生活的新篇章

在现代社会的快节奏中&#xff0c;每一位成员都在寻求更好的方式来适应环境&#xff0c;对于盲人群体而言&#xff0c;这种适应性尤为关键。盲人社会适应性训练作为一个旨在提升盲人生活质量和独立性的系统性过程&#xff0c;正逐步受到广泛关注。在这一过程中&#xff0c;一款…

安灯呼叫系统解决方案在生产中的应用

工厂安灯呼叫系统是一种用于监控工厂设备运行情况和生产状况的系统。它通常包括各种传感器和监控设备&#xff0c;可以实时监测工厂的生产流程&#xff0c;提供运行状态、故障警报、生产效率等信息。通过工厂安灯系统&#xff0c;工厂管理人员可以及时了解生产情况&#xff0c;…

探数API统计分享-中国各省人均消费支出

根据2017年至2021年的统计数据&#xff0c;我国各省&#xff08;市、区&#xff09;的人均消费支出情况各不相同。其中&#xff0c;上海的人均消费支出最高&#xff0c;达到了2021年的48879元&#xff0c;位居全国之首。紧随其后的是北京&#xff0c;人均消费支出为43640元。 相…

肯尼亚大坝决堤反思:强化大坝安全监测的必要性

一、背景介绍 近日&#xff0c;肯尼亚发生了一起严重的大坝决堤事件。当地时间4月29日&#xff0c;肯尼亚内罗毕以北的一座大坝决堤&#xff0c;冲毁房屋和车辆。当地官员称&#xff0c;事故遇难人数已升至71人。这起事件再次提醒我们&#xff0c;大坝安全无小事&#xff0c;监…

【机器学习高级】强化学习综述

文章目录 一、说明二、强化学习是什么&#xff1f;2.1 与现代神经网络的相异2.2 强化学习属于行为学派2.3 强化学习数学支持 三、强化学习有什么好处&#xff1f;3.1 在复杂环境中表现出色3.2 需要较少的人际互动3.3 针对长期目标进行优化 四、强化学习有哪些用例&#xff1f;4…

到底什么是数字?

来源&#xff1a;Bulletins from the Wolfram Physics Project 一、说明 数字这个概念是最普遍而又最难把控的概念。对数字概念的深度解读&#xff0c;决定人类社会方方面面的整体水平。而且&#xff0c;随着宇宙知识的认识&#xff0c;数字概念也似乎在膨胀中。 外星人乘坐星际…

Transformer,革命性的深度学习架构

Transformer 是一种革命性的深度学习架构,专门设计用于处理序列数据,特别是在自然语言处理(NLP)任务中表现卓越。它由 Vaswani 等人在 2017 年发表的论文《Attention is All You Need》中首次提出,打破了当时基于循环神经网络(RNN)和卷积神经网络(CNN)的序列建模常规,…

Tailwind CSS快速入门

文章目录 初识安装Tailwindcss试用安装快速书写技巧扩展好处Todo 初识 只需书写 HTML 代码&#xff0c;无需书写 CSS&#xff0c;即可快速构建美观的网站 Tailwind CSS 是一个功能类优先的 CSS 框架&#xff0c;它通过提供大量的原子类&#xff08;utility classes&#xff09;…

【Android14 ShellTransitions】(二)创建Transition

这一节的内容在WMCore中&#xff0c;主要是创建Transition&#xff0c;初始化其状态为PENDING。 还是我们之前说的&#xff0c;我们以在Launcher界面点击App图标启动某个App为例&#xff0c;来分析Transition的一般流程。启动Activity的流程&#xff0c;在ActivityStarter.star…

[桌面端应用开发] 从零搭建基于Caliburn的图书馆管理系统(C#合集)

图书馆系统要求&#xff1a; 你是一家新市图书馆的经理。 图书馆拥有大量藏书和不断增长的会员。 为了使图书馆管理更加容易&#xff0c;现在创建一个图书馆管理系统。 图书馆管理系统应具备以下功能&#xff1a; 1.图书管理&#xff1a;系统应该能够向图书馆添加新图书。 每本…

【Linux-驱动开发】

Linux-驱动开发 ■ Linux-应用程序对驱动程序的调用流程■ Linux-file_operations 结构体■ Linux-驱动模块的加载和卸载■ 1. 驱动编译进 Linux 内核中■ 2. 驱动编译成模块(Linux 下模块扩展名为.ko) ■ Linux-■ Linux-■ Linux-设备号■ Linux-设备号-分配■ 静态分配设备号…

【设计模式深度剖析】【2】【结构型】【装饰器模式】| 以去咖啡馆买咖啡为例 | 以穿衣服出门类比

&#x1f448;️上一篇:代理模式 目 录 装饰器模式定义英文原话直译如何理解呢&#xff1f;4个角色类图1. 抽象构件&#xff08;Component&#xff09;角色2. 具体构件&#xff08;Concrete Component&#xff09;角色3. 装饰&#xff08;Decorator&#xff09;角色4. 具体装饰…