• 最新论文
  • 央行年内第二次降准:释放9000亿 还有两大利好 曾在纽时批特朗普的白宫匿名官员 出书阻止他连任 看完这篇JVM,阿里面试官都不怕! 备战2022卡塔尔世界杯 足协公布预选赛集训名单 央行年内第二次降准:释放9000亿 还有两大利好 看完这篇JVM,阿里面试官都不怕! 辽宁:村支书基本报酬不低于村民人均收入两倍 辽宁:村支书基本报酬不低于村民人均收入两倍 看完这篇JVM,阿里面试官都不怕! 团伙设高价收购网络关键词骗局 30多人被骗155万 团伙设高价收购网络关键词骗局 30多人被骗155万 看完这篇JVM,阿里面试官都不怕! 《安家》强势孙俪大战佛系罗晋,因撬单被同事嘲讽:吃相难看
  • 推荐论文
  • 央行年内第二次降准:释放9000亿 还有两大利好 曾在纽时批特朗普的白宫匿名官员 出书阻止他连任 看完这篇JVM,阿里面试官都不怕! 备战2022卡塔尔世界杯 足协公布预选赛集训名单 央行年内第二次降准:释放9000亿 还有两大利好 看完这篇JVM,阿里面试官都不怕! 辽宁:村支书基本报酬不低于村民人均收入两倍 辽宁:村支书基本报酬不低于村民人均收入两倍 看完这篇JVM,阿里面试官都不怕! 团伙设高价收购网络关键词骗局 30多人被骗155万 团伙设高价收购网络关键词骗局 30多人被骗155万 看完这篇JVM,阿里面试官都不怕! 《安家》强势孙俪大战佛系罗晋,因撬单被同事嘲讽:吃相难看
  • 热门标签
  • 日期归档
  • 看完这篇JVM,阿里面试官都不怕!

    来源:www.bloodonthemotorway.com 发布时间:2020-03-17

    前言:“只有秃顶才能变得强壮。”这已经包含在我的GitHub精选中。欢迎来到星空:

    学习JVM的目的也很简单:

    可以知道JVM是什么,它为我们做了什么,以及具体是如何做的。能够理解一些我初学时不理解的事情

    在面试时有对话信息

    可以假装强制

    声明:默认情况下,全文引用热点虚拟机

    1。让我们来谈谈JVM

    1.1。让我们来看看一个简单的Java程序

    现在我有了一个JavaBean:

    一个测试类:

    当我们还是初学者时,我们必须编译文件代码并使用命令来执行编译后的文件。

    Java源文件:

    当使用IDE点击运行时,它实际上是这两个命令(编译和运行)的组合,以便于我们的开发。

    Generate class File

    Parse class File Result

    Java源代码编译由以下三个过程组成:

    File由Java源代码编译器(上面提到的javac.exe)完成。流程图如下:

    Java源代码编译由以下三个过程组成:

    符号表的分析和输入

    注释处理

    语义分析和生成类文件

    1.2.1编译期-语法糖

    语法糖可以看作是编译器实现的一些“技巧”,这些“技巧”可能会导致效率的“大幅度提高”。

    最值得注意的是泛型。这种语法糖可以说是我们经常使用的!

    泛型只存在于Java源代码中,编译后将被原始的原始类型(也称为裸类型)替换。这个过程也称为一般擦除。

    有了泛型的语法糖:

    代码更简洁[没有强制转换]

    程序更健壮[只要编译时没有警告,运行时不会有ClassCastException异常]

    可读性和稳定性[编写集合时,只有类型是有限的]

    了解更多关于泛型的信息:

    1.3 JVM实现跨平台

    到目前为止,我们已经通过编译器编译了我们的源代码文件来生成文件!

    这些文件显然不能直接运行,不像C语言(编译cpp后生成的exe文件直接运行)

    这些文件被提交给JVM进行解析和运行!

    JVM运行在操作系统上,每个操作系统的指令是不同的,JDK不同于操作系统。只要你的本地系统配备了JDK,这个JDK就能与当前的系统兼容。

    类字节码在JVM上运行,所以哪个操作系统编译类字节码并不重要。只要符合JVM规范,字节码文件就是可运行的。

    因此,Java是跨平台编译的,并且可以在任何地方运行!

    1.4类文件和JVM的世仇

    1.4.1类加载时间

    我们示例中生成的两个文件现在会直接加载到JVM中吗?

    virtual machine规范严格规定类必须“初始化”(类文件被加载到JVM中),只有5种情况:

    创建类的实例(新方法)。访问类或接口的静态变量,或者给静态变量赋值,调用类的静态方法

    reflection

    初始化类的子类,当Java虚拟机启动时,其父类也将被初始化

    标记为启动类的类。直接使用java.exe命令运行一个主类(包含主方法的类)

    所以:

    Java类加载是动态的。它不会在一次加载完所有类后运行,但会确保程序运行的基本类(如基类)完全加载到jvm中,而其他类会在必要时加载。这当然是为了节省内存开销。

    class文件中是通过类的加载器加载到jvm中的!

    Java默认有三种类型的加载器:

    每个加载器的工作职责:

    1)引导类加载器:负责在$Java_HOME的jre/lib/rt.jar中加载所有类,由c实现。非类加载器子类

    2)扩展类加载器:一些jar包负责在JAVA平台中加载扩展函数,包括jre/lib/ext/*下的jar包。jar或-Djava.ext.dirs在$JAVA_HOME中指定的目录

    3)应用类加载器:负责记录类路径中指定的jar包和目录中的class

    工作进程:

    1。当AppClassLoader加载一个类时,它不会先尝试加载类本身,而是将类加载请求委托给父类加载器ExtClassLoader来完成。

    2。当ExtClassLoader加载类时,它不会先尝试加载类本身,而是将类加载请求委托给BootStrapClassLoader来完成。

    3。如果BootStrapClassLoader加载失败(例如,在$JAVA_HOME/jre/lib中找不到该类),将使用ExtClassLoader尝试加载;

    4。如果ExtClassLoader也无法加载,将使用AppClassLoader加载

    5。如果AppClassLoader也无法加载,将会报告异常ClassNotFoundException

    异常。事实上,这就是所谓的父委托模型。简单地说:如果类加载器收到一个加载类的请求,它不会先尝试加载类本身,而是将请求委托给父加载器完成,一个接一个向上。

    好处:

    防止内存中同一字节码的多个副本(从安全角度来看)

    特殊指令:

    类装入器在成功装入一个类后缓存结果类的实例。下次请求加载类时,类加载器将直接使用类的缓存实例,而不是再次尝试加载它。将

    1.4.2类加载详细过程

    loader加载到jvm中,然后有几个步骤:

    加载、查找和加载该类的二进制数据,并在java堆中创建java.lang.Class类的对象。

    Connection,该连接包含另外三个部分:验证、准备和初始化。

    1)验证,文件格式、元数据、字节码和符号引用的验证;

    2)准备为类的静态变量分配内存,并将它们初始化为默认值;

    3)解析,将类中的符号引用转换为直接引用

    initialization,为类的静态变量提供正确的初始值。

    1.4.3JIT即时编辑器

    一般来说,我们可能会认为:在加载这些类文件之后,JVM将逐个取出这些字节码,并逐个执行C解析器解析。

    但是如果是这样的话,那就太慢了!

    我们的JVM是这样实现的:

    它是重新编译和优化这些Java字节码,以生成机器代码供CPU直接执行。这样编译的代码将会更加高效。

    编译也需要时间。我们通常编译热代码,直接解析非热代码是好的。

    热点代码解释:调用了一个或多个方法。其次,多次执行的循环体使用HotSpot检测来检测它是否是热点代码。热点检测有两种方法:

    sampling

    counter

    Hotspot目前使用计数器方法,该方法为每种方法准备两种类型的计数器:

    method call counter

    Back EdgeCounter。

    在确定虚拟机运行参数的前提下,两个计数器都有一定的阈值。当计数器超过阈值时,将触发JIT编译。

    1.4.4返回示例

    根据我们的程序,我们的文件将由AppClassLoader加载到JVM中(因为ExtClassLoader和BootStrap加载器都不会加载到[父委托模型中)。

    后来发现了要使用的类Java3y。我们的文件将由AppClassLoader加载器加载到JVM中(因为ExtClassLoader和BootStrap加载器都不会加载到[父委托模型中))

    详见

    加载类文件简介

    扩展的JVM阅读对话:

    深入讨论Java ClassLoader

    加载

    1.5类后,JVM做了什么?

    类加载检查通过后,虚拟机将为新对象分配内存。

    JVM的内存结构是基于jdk1.8绘制的我画得更仔细了。

    首先,让我们看看JVM的内存结构是什么样子的:

    JVM的内存结构是基于jdk1.8绘制的我画得更仔细了。

    ![图片描述][1]

    简单看看内存结构,看看每个区域实际存储了什么(它做什么):

    堆:存储对象实例,其中几乎所有对象实例都分配内存

    虚拟机堆栈:虚拟机堆栈描述了Java方法执行的内存结构:当每个方法被执行时,创建一个堆栈框架来存储诸如本地变量表、操作堆栈、动态链接、方法出口

    本地方法堆栈等信息:本地方法堆栈为虚拟机使用的本机方法服务。

    方法区:存储虚拟机加载的类元数据信息(元空间)。

    程序计数器:当前线程执行的字节码的行号指示符

    1.5.2 Process

    让我在宏级别上简要描述我们示例中的工作流:

    1。通过运行,它被加载到JVM中,元空间存储类信息(包括类名、方法信息、字段信息等)。)。

    2,然后JVM找到Java3yTest的主函数条目(main ),为主函数创建一个堆栈框架,并开始执行主函数

    3。主函数的第一个命令是让JVM创建一个Java3y对象,但是此时方法区域中没有Java3y类信息,所以JVM立即加载Java3y类。将Java3y类类型信息放入方法区域(元空间)

    4。在加载了Java3y类之后,Java虚拟机做的第一件事就是在堆区域中为新的Java3y实例分配内存,然后调用构造函数来初始化Java3y实例,该实例保存指向方法区域(包含方法表)的Java3y类类型信息。在使用java 3Y时,JVM根据java3y引用找到Java3y对象,然后根据Java3y对象持有的引用在方法区域中定位Java 3Y类类型信息方法表,获得函数的字节码地址

    6,为函数创建堆栈帧,并开始运行函数

    。事实上,很多事情都是在显微镜下完成的。正如上面提到的类加载过程(加载C连接(验证、准备、解析)C初始化),jvm在类加载后为类分配内存(在分配内存方面已经做了很多事情)。由于这些步骤不是一步一步走下去的,将会有许多“混乱的自举”过程,所以很难清楚地描述它们。

    扩展阅读(Class Object First or Object First):

    Reference:

    . html-Java程序编译和运行过程

    JVM运行机制和基本原则

    1.6常量池简介

    在撰写本文时,我认为我不再是类似主题的问题,直到我遇到了这样的方法,并将其与诸如混合之类的东西一起使用时,我发现自己还太年轻。

    首先,我读了美国技术团队的这篇文章: _深度_理解_ String _ inter . html-String # intern的深入分析

    嗯,然后我被淹没了。我摘录了他的例子:

    改变位置后:

    JDK 7,8以下为假真

    改变位置后:

    打印结果是:

    JDK 7,8以下为假

    文章中有一个非常详细的分析,但读了几遍后我还是很困惑。因此,我知道我的知识点还有漏洞。我读了一些在R大学之前写的文章:

    停止使用“字符串s=新字符串(“XYZ”);看完之后,我更迷惑了,到底有多少字符串被创建成了“访问”。

    后来,我在胡志上看到了这个答案:

    在新字符串中的“文字”是否进入了字符串常量池?

    将在线数据与自己的想法结合起来,让我们整理出对常数池的理解~ ~

    1 . 6 . 1 JD k 1.7后每个常数池的情况

    运行时常数池在堆中

    字符串常数池在堆中

    常数池存储:

    文字:文本字符串等。-用双引号括起来的字符串的文字值将进入接口的

    符号引用)

    类和全名的名称和描述符)

    字段。

    方法名和描述符

    常量池表,用于存储编译时生成的各种文字和符号引用。这部分内容将在类加载后存储在方法区域的运行时常量池中-源代码:对Java虚拟机JVM高级特性和最佳实践的透彻理解(第二版)

    现在我们的运行时常量池刚刚改变了它的位置(最初来自方法区域,但是现在在堆中),但是很清楚的是在类被加载之后,常量池中的数据将被存储在运行时常量池中!

    其他人总结的常量池:

    它是类文件中的内容,而不是运行时内容,不理解它是一个池,它实际上是类文件中的字节码指令

    字符串常量池:

    HotSpot虚拟机,一个记录中间字符串的全局表被称为StringTable,它本质上是一个哈希表。请注意,它只存储对java.lang.String实例的引用,而不是String对象的内容

    string常量池只存储引用,而不是内容!

    让我们再看看我们的实习方法:

    如果当前字符串存在于常量池中,那么直接返回它在常量池中的引用。

    如果常量池中不存在该字符串,对该字符串的引用将保存在常量池中,然后直接返回!

    1.6.2标题的解释

    原本打算通过注释的方式来解释,但似乎很难说清楚。让我画一幅图…

    第一句:

    第二句:发现“1”字符串对象已经存在于字符串常量池中,直接返回对字符串常量池中堆的引用(但没有收到)c此时,s引用仍然指向堆中的对象

    第三句:发现字符串常量池已经保存了对对象的引用, 直接从字符串常量池

    返回对堆中的字符串的引用很容易看出,这两个引用是不同的! 所以它返回false。

    第一句话:注意:此时**'11 '对象不保存字符串常量池**中的引用。

    第二句:发现“11”对象不在字符串常量池中,因此“11”对象将当前字符串的引用保存在字符串常量池中,并返回当前字符串的引用(但未收到)

    第三句:发现该引用已经存在于字符串常量池中。直接返回(获取与s3相同的引用)

    根据上面的语句:它将返回true~~~

    如果您仍然不清楚,您可以尝试接收方法的返回值并查看上面的图,然后您应该理解。

    下面将由你们所有人来做,看看你们是否掌握了:

    另外:

    1.7垃圾收集

    可以说垃圾收集是JVM中一个非常重要的知识点,应该详细解释。但是在我学习的路上,我找到了一篇解释垃圾收集的好文章。

    因此,我在这里只简单介绍一下垃圾收集。详情请参考以下问题,最后给出相关信息。

    Read ~

    1.7.1JVM垃圾收集简介

    在C语言中,我们知道创建的对象需要手动删除。我们的Java程序在JVM中运行。JVM可以帮助我们“自动”回收不必要的对象,这对我们来说非常方便。

    虽然有人说“自动”回收我们不需要的东西,但如果我们想变得更强,我们必须变得秃顶.不,我们必须弄清楚它是如何工作的,它有什么理论知识。

    首先,JVM回收垃圾,这在我们的程序中已经没有必要了。在垃圾收集器回收堆之前,首先要确定这些对象中哪些是“活动的”,哪些是“死的”判断哪些对象是“死的”有两种方法:

    reference计数法,这很难解决对象之间的循环引用问题。

    可达性分析算法C的主流JVM使用这个方法

    现在可以判断哪些对象是“死的”。我们现在将回收这些“死”的物体。还有几种回收算法:

    标记-清除算法

    复制算法

    标记-排序算法

    生成收集算法

    (关于这些算法的详细信息,请参见下面的问题)~

    无论是可达性分析算法还是垃圾收集算法,JVM都使用精确的GC。JVM使用一组称为OopMap的数据结构来存储所有的对象引用(这样就不必遍历整个内存来查找,空间会改变时间)。

    并且不会为所有指令生成OopMap只有面向对象的地图将在安全点生成,而垃圾收集将在安全区域启动。

    在OopMap的帮助下,HotSpot可以快速准确地完成GC根枚举(可达性分析)。

    上述垃圾收集算法只能被视为方法,垃圾收集器是在地面上实现的:

    串行收集器

    ParNew收集器

    Parallel Goverage收集器

    Parallel Lod收集器

    Parallel Lod收集器

    CMS收集器

    G1收集器

    上述大多数收集器都是

    1.8JVM参数和调优

    许多完成了JavaWeb项目(ssh/ssm)的学生可能遇到了诸如OutOfMemory之类的错误。一般来说,解决它也很方便。启动时只需添加一个参数。

    上面也说了很多关于JVM的事情JVM对内存的划分,JVM对各种垃圾收集器的划分。

    内存分配的大小和使用哪个收集器可以由我们根据自己的需要和实际情况来指定,所以我们不在这里详述。当你真的需要的时候,请回来填这个坑~ ~ ~

    参考:

    . cn blogs . com/rede screen/archive/2011/05/04/ . html-jvm series : JVM参数设置,分析

    2,JVM表面测试问题

    带一些常见的JVM表面测试问题去做,加深理解并检查缺陷和泄漏:

    1,详细的JVM内存结构

    2,告诉我下次有内存溢出和泄漏时会发生什么

    3。给我讲讲Java线程堆栈

    4。从年轻一代到老一代的JVM升级过程的判断标准是什么?

    5。完全垃圾回收在JVM中非常常见。我如何在线解决问题?

    6。为什么类加载使用父委托模式?有没有打破这种模式的场景?

    7,类实例化顺序

    8,jvm垃圾收集机制,什么时候触发MinorGC等操作

    9,什么是完整的垃圾收集过程(从ygc到fgc)在JVM

    10中,各种回收器,各自的优缺点,重点是CMS,G1

    11,各种回收算法

    12,OOM错误,stackoverflow错误,Permgen空间错误

    topic source:

    2.1详细的JVM内存结构

    根据JVM规范,JVM内存分为五个部分:虚拟机堆栈,堆,方法

    可能会专门讨论jdk1.7之前的PermGen(永久生成)并将其替换为Metaspace。

    数据最初存储在永久代中:符号被传输到本机映射;字面术语(中间字符串)被转移到java堆;类的静态变量(类静态)被转移到java堆

    元空间(meta-space),后者存储类的元数据信息(metadata)

    元空间。元空间的本质类似于永久生成,它是JVM规范中方法域的实现。然而,元空间和永久生成之间的最大区别在于,元空间不在虚拟机中,而是使用本地内存。

    replacement的好处:首先,字符串存在于永久代中,这容易导致性能问题和内存溢出。第二,永久生成会给气相色谱带来不必要的复杂性,而且恢复效率很低

    Image Source:

    参考:

    2.2告诉我下次出现内存溢出和内存泄漏时会发生什么?

    内存泄漏的原因很简单:

    对象是可访问的(总是被引用的)

    但是对象不会被使用。

    常见的内存泄漏示例:

    解决这个内存泄漏问题也很简单,设置为空,可以避免引发内存泄漏问题。其他内存泄漏已经被一步一步地分析了。

    内存泄漏引用:

    内存溢出原因:

    内存泄漏导致堆栈内存增长,导致内存溢出。

    加载了大量jar类文件,没有足够的空间来加载类。大量对象的Overflow

    操作会导致堆内存空间满。溢出

    nio直接操作内存,过大的内存会导致溢出

    Resolve:

    检查程序是否有内存泄漏。

    设置参数以增加空间。

    检查代码中是否有死循环或重复次数过多的对象实体。

    检查nio是否直接操作内存。

    参考:

    2.3谈论线程堆栈

    这里的线程堆栈应该是指虚拟机堆栈…

    JVM规范允许每个Java线程拥有自己独立的JVM堆栈,它也是Java方法的调用堆栈。

    当调用该方法时,会生成一个堆栈帧。堆栈帧存储在虚拟机堆栈中。堆栈帧存储局部变量表、操作数堆栈、动态连接、方法返回地址和方法的其他信息

    在线程运行过程中,只有一个堆栈帧处于活动状态,称为“当前活动堆栈帧”。当前活动堆栈框架始终是虚拟机堆栈的顶部元素。

    通过jstack工具

    Reference查看线程状态:

    /Article/Details/

    2.4判断年轻一代向老一代JVM升级过程的标准是什么?

    一些对象将被复制到“从”和“到”区域,并将被交换15次(由JVM参数MaxTenuringThreshold决定,默认值为15)。如果他们还活着,他们将被保存到老年。

    如果对象的大小大于伊甸园的一半,它将被直接分配给旧的。如果旧的不能分配它,它将做一个大的。如果它比伊甸园的一半小,但没有足够的空间,它会做迷你画,也就是新一代的gc。经过

    小gc,幸存者仍然不能放下,然后把它放入老年

    动态年龄判断。大于或等于某个年龄的对象超过幸存空间的一半,而大于或等于某个年龄的对象直接进入老年

    2.5jvm。fullGC非常常见。如何在线解决问题

    此问题基于完全垃圾收集的触发条件:

    如果存在垃圾收集(jdk1.8已不存在),将为垃圾收集分配空间,但如果空间不足,将触发完全垃圾收集。

    让我们看看perm gen面积的值是否太小。

    Method Call

    这一般不叫~ ~

    当提升到老一代的小垃圾收集器的平均大小大于老一代的剩余空间时,将触发全垃圾收集器(这可以从多个角度看到)

    是否经常创建大对象(伊甸园区域也可能设置得太小)(大对象在老一代直接分布。这导致老年时空间不足因此经常发生垃圾收集)

    老年时的空间设置是否太小(小垃圾收集的几个对象大于老年时的剩余空间)

    2.6类加载为什么使用父代委托模式?是否有任何情况会破坏这种模式?

    父委托模型的重要目的是解决类加载过程中的安全问题。

    假设一个开发人员写了一个名为自己的类来欺骗JVM。现在他将使用定制来加载他编写的类。

    然而幸运的是,父母的信任模式不允许他成功。因为JVM将首先在的路径下找到该类,并将其加载到Java中。类加载总是遵循父委托模型吗?

    在实际开发中,我们可以通过定制类加载器和重写父类的loadClass方法来打破这种机制。

    SPI破坏了父母信任机制(SPI:服务发现)。SPI信息:

    引用:

    Reference查看线程状态:

    2.7类实例化顺序

    1。父类静态成员和静态初始化块,执行

    2。子类静态成员和静态初始化块按照它们在代码中出现的顺序排列。按代码中出现的顺序执行

    3。父类实例成员和实例初始化块按顺序执行。按照代码中出现的顺序执行

    4。父类构造方法

    5。子类实例成员和实例初始化块按照它们在代码中出现的顺序执行。子类构造方法

    检查它是否被真正理解:

    输出数据:

    第一次犯错误的学生指出一个称赞。不要太在意(hahaha

    2.8JVM垃圾收集机制,当年轻一代中的伊甸园区域完全分配给触发Minorgc时(当没有足够的空间给新一代时),何时触发Minorgc

    等操作)。在

    2.9JVM

    YGC中,什么是完整的垃圾收集过程(从ygc到fgc),什么是FGC

    YGC:新一代堆的垃圾收集。这一频率相对较高,因为大多数物体寿命较短,在新生代被回收。性能成本更低。

    FGC:全堆范围的GC。当默认堆空间使用率达到80%(可调)时,将触发Fgc。以我们的生产环境为例,fgc很少被触发,有时每10天或大约一周触发一次。

    当没有足够的空间来执行ygc和FGC

    a.eden,没有足够的空间来执行Youngc

    b.old,没有足够的perm空间,调用方法,YGC的悲观策略,转储活动中的内存信息(jmap Cdump:live),将执行Fulgc

    2.10。有三种基本算法

    我们常用的复制算法

    标签压缩算法

    垃圾收集器一般采用逐代收集算法(事实上,以上算法是结合在一起的,不同的区域使用不同的算法)。

    Specific:

    Mark-Sweep算法与其名称一样,分为两个阶段:标记和扫描:首先,标记所有要回收的对象,然后在标记完成后统一回收所有标记的对象。

    replication algorithm,“复制”的集合算法,根据容量将可用内存分成两个大小相等的块,并且一次只使用其中一个。当这段内存用完时,将幸存的对象复制到另一段,然后再次清理已使用的内存空间。

    marking-compression算法,标记过程仍与“marking-clearing”算法相同,但后续步骤不是直接清理可回收对象,而是将所有活对象移动到一端,然后直接清理内存边界以外的端

    分代收集算法,即“分代收集”算法,该算法将Java堆分为新一代和老一代,以便根据每一代的特点采用最合适的收集算法。

    2.11每一种回收机都有其优点和缺点。关键的内容管理系统和G1

    地图是从《深入理解Java虚拟机:JVM高级特效与最佳实现》。地图上的两个收集器之间有联系,这表明它们可以一起使用。

    串行采集器。串行收集器是最古老、最稳定和最高效的收集器,但它可能会导致长时间的暂停,并且只使用一个线程来回收。

    ParNew收集器,ParNew收集器实际上是串行收集器的多线程版本。

    并行收集器,并行清除收集器类似于新收集器,并行收集器更注重系统吞吐量。

    并行旧收集器,并行旧收集器是并行清除收集器的老式版本。它使用多线程“标记和排序”算法

    CMS收集器,并且CMS(并发标记扫描)收集器是一种旨在获得最短恢复暂停时间的收集器。它需要消耗额外的CPU和内存资源,当CPU和内存资源紧张且CPU很小时,这将增加系统负担。CMS不能处理浮动垃圾。CMS的“标记和清除”算法将导致大量的空间碎片。

    G1收集器,G1(垃圾优先)是一个面向服务器的垃圾收集器,主要针对配备多处理器和大内存的机器。它以极高的概率满足气相色谱暂停时间要求,并具有高吞吐量性能特征。

    2.12stackoverflow错误。Permgen空间错误

    stackoverflow错误主要发生在:

    在虚拟机堆栈中(线程请求的堆栈深度大于虚拟机堆栈锁允许的最大深度)

    permgen空间错误(对于jdk之前的1.7版本):

    大量加载类文件

    常量池内存溢出

    3。概要

    一般来说,JVM在初级阶段仍然是理论性的,可能需要做一些具体的事情,然后才能有更深入的经验。这篇文章主要是关于进门的~

    参考:

    《深入理解Java虚拟机 JVM高级特性与最佳实践(第二版)》

    纯笑jvm栏目:

    sexy code JVM栏目: Page=1

    javaGC流程: /article/details/

    如果你想实时观看我的更新文章和干货,请观看我的公开号码“Java3y”。

    Java精致脑地图

    Java学习路线

    开发通用工具

    回复“888”公共号码获取!

    已包含在我的GitHub选择中。欢迎来到明星:

    评论和关注?请分享并留言,这对我真的很有用!

    -

    友情链接: