
JVM
文章平均质量分 89
JVM (Java Virtual Machine 简称 JVM),亦可称之为 Java 虚拟机。它是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,它是 Java 最具吸引力的特性之一。
我心向阳iu
CSDN专家博主、阿里云开发者社区专家博主、51CTO社区专家博主、360书馆认证博主、知乎掘金B站等平台受邀作者。
如遇开发、程序等需求,博客首页下拉加入公众号,私信博主
展开
-
JVM内存模型与Java线程内存模型的区别
总的来说,JVM内存模型和Java线程内存模型是Java程序运行时的两个重要方面,它们共同构建了一个稳定、高效的Java运行环境。JVM内存模型提供了整体的框架,而Java线程内存模型则在多线程情境下保证了数据的正确性和可见性。它是线程私有的,随着线程的创建而创建,随着线程的销毁而销毁。JVM内存模型主要关注Java程序在运行时的内存组织,而Java线程内存模型关注多线程环境下的数据共享和同步机制。JVM内存模型是整个Java虚拟机的内存结构,而Java线程内存模型则是在多线程环境下对内存的一种抽象。原创 2024-01-03 16:24:16 · 1188 阅读 · 0 评论 -
场景应用:Java 出现 Out Of MemoryError(OOM 错误)的原因有哪些?出现 OOM 错误后,怎么解决?
错误原因:此 OOM 是由于 JVM 在 GC 时,对象过多,导致内存溢出,建议调整 GC 的策略,在一定比例下开始 GC 而不要使用默认的策略,或者将新代和老代设置合适的大小,需要进行微调存活率。解决方法:如果 JVM 内存调的过大或者可利用率小于 20%,可以建议将 heap 及 perm 的最大值下调,并将线程栈调小,即-Xss 调小,如:-Xss128k。显示的是提示分配失败的源模块的名称,所以有必要查看日志文件,如 crash 时的 hs 文件。解决方法:调高 heap 的最大值,即。原创 2022-10-16 09:02:59 · 1829 阅读 · 0 评论 -
Minor GC、Young GC、Old GC、Major GC、Mixed GC、Full GC都是什么?
所以如果讨论 Major GC 的时候需要指定前提到底是讨论的是 old GC 还是 Full GC,比如周志明版的《深入理解虚拟机》就把 old GC 统称为 【Major GC】,这里我们先按照 old GC == Major GC 讨论。此时这个新生代gc,其实就是所谓的“Minor GC”,也可以称之为“Young GC”,这两个名词,就专门针对新生代的gc。从字面意思上也可以理解,“Full”就是整体的意思,所以就是对JVM进行一次整体的垃圾回收,把各个内存区域的垃圾都回收掉。原创 2022-09-26 10:40:40 · 3204 阅读 · 0 评论 -
JVM基础:什么是STW?
无语,仔细回忆了下,知道Stop-The-World这个词,不知道SWT,无语。原创 2022-09-24 23:20:38 · 2455 阅读 · 0 评论 -
图解 Java 跨平台原理(字节码文件、虚拟机)
Java 虚拟机是可运行 Java 字节码文件的虚拟计算机。不同平台的虚拟机是不同的,但它们都提供了相同的接口。Java 语言具有一次编译,到处运行的特点。就是说编译后的.class 可以跨平台运行,前提是该平台具有相应的 Java 虚拟机。但是性能比 C/C++要低。Java 源程序(.java)要先编译成与平台无关的字节码文件(.class),然后字节码文件再解释成机器码运行。例如下面的Windows系统中C语言编译执行过程,如果要到Linux上,还需要C源程序进行编译成Linux可执行文件再执行。原创 2022-09-21 21:29:36 · 1809 阅读 · 0 评论 -
CMS垃圾收集器详解(转载)
CMS垃圾回收器设计目的:为了避免「老年代 GC」出现「长时间」的卡顿(Stop The World)CMS垃圾回收器回收过程:初始标记、并发标记、并发预处理、重新标记和并发清除。初始标记以及重新标记这两个阶段会Stop The WorldCMS垃圾回收器的弊端:会产生内存碎片&&需要空间预留:停顿时间是不可预知的。转载 2022-09-25 14:51:55 · 3624 阅读 · 3 评论 -
G1收集器详解(转载)
CMS垃圾收集器的弊端:会产生内存碎片 && 需要预留空间。这两个问题在处理时,很有可能会导致停顿时间过长,即CMS的停顿时间不可预知。所以G1又可以理解为在CMS垃圾收集器上进行了"升级"。转载 2022-09-25 14:32:20 · 349 阅读 · 0 评论 -
真实系统优化:JVM参数调优建议与实战
但是,当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集器找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5。比如设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。例如:-Xmn2g:设置年轻代大小为2G。原创 2022-11-11 16:07:31 · 2369 阅读 · 0 评论 -
JVM之内存泄漏和内存溢出
严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。内存溢出(out of memory):简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出。:内存泄漏指程序运行过程中分配内存给临时变量,用完之后却没有被GC回收,始终占用着内存,既不能被使用也不能分配给其他程序,于是就发生了内存泄漏。:简单地说内存溢出就是指程序运行过程中申请的内存大于系统能够提供的内存,导致无法申请到足够的内存,于是就发生了内存溢出。内存泄漏的根本原因是。原创 2022-08-23 08:00:49 · 1750 阅读 · 0 评论 -
关于 G1(Garbage First)垃圾收集器
更具体的处理思路是让G1收集器去跟踪各个Region里面的垃圾堆积的“价值”大小,价值即回收所获得的空间大小以及回收所需时间的经验值,然后在后台维护一个优先级列表,每次根据用户设定允许的收集停顿时间(使用参数-XX:MaxGCPauseMillis指定,默认值是200毫秒),优先处理回收价值收益最大的那些Region,这也就是“Garbage First”名字的由来。G1收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。原创 2022-08-22 23:25:37 · 1321 阅读 · 0 评论 -
Java的垃圾回收机制详解——从入门到出土,学不会接着来砍我!
每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。但是,在Java领域,至少主流的Java虚拟机里面都没有选用引用计数算法来管理内存,主要原因是,这个看似简单的算法有很多例外情况要考虑,必须要配合大量额外处理才能保证正确地工作,譬如单纯的引用计数就很难解决对象之间相互循环引用的问题。举个简单的例子:对象objA和objB都有字段instance,赋值令objA.instance=objB及。原创 2022-08-22 22:54:22 · 6246 阅读 · 2 评论 -
JVM GC 分代收集理论的推演(阅读与思考)
假如要现在进行一次只局限于新生代区域内的收集,但新生代中的对象是完全有可能被老年代所引用的,为了找出该区域中的存活对象,不得不在固定的GC Roots之外,再额外遍历整个老年代中所有对象来确保可达性分析结果的正确性,反过来也是一样。最早出现也是最基础的垃圾收集算法是“标记-清除”(Mark-Sweep)算法,如它的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象,也可以反过来,标记存活的对象,统一回收所有未被标记的对象。原创 2022-08-22 20:26:05 · 1452 阅读 · 0 评论 -
JVM的类加载器,以及双亲委派模型都是什么?
反之,如果没有使用双亲委派模型,都由各个类加载器自行去加载的话,如果用户自己也编写了一个名为java.lang.Object的类,并放在程序的ClassPath中,那系统中就会出现多个不同的Object类,Java类型体系中最基础的行为也就无从保证,应用程序将会变得一片混乱。例如类java.lang.Object,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都能够保证是同一个类。原创 2022-08-22 16:46:42 · 1447 阅读 · 0 评论 -
Java对象的实例化过程是怎样的?
但如果Java堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“除如何划分可用空间之外,还有另外一个需要考虑的问题:对象创建在虚拟机中是非常频繁的行为,即使仅仅修改一个指针所指向的位置,在并发情况下也并不是线程安全的,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。原创 2022-08-22 15:14:48 · 3190 阅读 · 2 评论 -
Java程序是怎么运行的?
而在类加载加载User类的时候,可以通过虚拟机获取Tool类的实际内存地址,因此便可以将符号com.Tool替换为Tool类的实际内存地址,即直接引用地址。在运行过程中,每当调用进入一个java方法,java虚拟机会在当前线程的java方法栈中生成一个栈帧,用以存放局部变量以及字节码的操作数。概括来说,写好的 Java 源代码文件经过 Java 编译器编译成字节码文件后,通过类加载器加载到内存中,才能被实例化,然后到 Java 虚拟机中解释执行,最后通过操作系统操作 CPU 执行获取结果。原创 2022-08-22 14:36:08 · 7382 阅读 · 0 评论 -
Java 类加载的过程
各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须都是一致的,因为符号引用的字面量形式明确定义在《Java虚拟机规范》的Class文件格式中。类型数据妥善安置在方法区之后,会在Java堆内存中实例化一个java.lang.Class类的对象,这个对象将作为程序访问方法区中的类型数据的外部接口。类的初始化阶段是类加载过程的最后一个步骤,之前介绍的几个类加载的动作里,除了在加载阶段用户应用程序可以通过自定义类加载器的方式局部参与外,其余动作都完全由Java虚拟机来主导控制。原创 2022-08-22 11:17:06 · 2993 阅读 · 0 评论 -
JVM是启动过程是怎样的?
运行jar 的时候,java.exe调用GetMainClassName函数,该函数先获得JNIEnv实例然后调用JarFileJNIEnv类中getManifest(),从其返回的Manifest对象中取getAttrebutes(“Main-Class”)的值,即jar 包中文件:META-INF/MANIFEST.MF指定的Main-Class的主类名作为运行的主类。JRE是Java的运行环境,是面向所有Java程序的使用者,包括开发者,即JRE = 运行环境 = JVM。JVM的装载工作完成。原创 2022-08-22 10:38:23 · 1323 阅读 · 0 评论 -
volatile关键字是干什么的?他是怎样实现的?
JMM 试图屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。原创 2022-08-21 15:08:45 · 1310 阅读 · 0 评论 -
Java代码的编译过程(没写完,不要点进来)
这个方法会判断是否还有新的注解处理器需要执行,如果有的话,通过JavacProcessing-Environment类的doProcessing()方法来生成一个新的JavaCompiler对象,对编译的后续步骤进行处理。这个方法会判断是否还有新的注解处理器需要执行,如果有的话,通过JavacProcessing-Environment类的doProcessing()方法来生成一个新的JavaCompiler对象,对编译的后续步骤进行处理。词法、语法分析,将源代码的字符流转变为标记集合,构造出抽象语法树。原创 2022-08-21 11:20:20 · 1696 阅读 · 0 评论 -
Java 语法糖以及常见的应用
简单的说,装箱就是自动将基本数据类型转换为包装器类型;我们先了解一下 语法糖 的概念:语法糖(Syntactic sugar),也叫做糖衣语法,是英国科学家发明的一个术语,通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。被认为是不同的类型,但是输出却得到了相等的结果,这是因为,泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。语法糖指的是计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。原创 2022-08-21 10:55:28 · 1469 阅读 · 1 评论 -
关于 CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种获取最短回收停顿时间为目标的收集器,目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间最短,以给用户带来较好的体验,CMS收集器就非常符合这类应用的需求。重新标记(CMS remark):重新标记则是为了修正并发标记期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。原创 2022-08-20 23:51:32 · 1317 阅读 · 0 评论 -
图解 JVM 内存结构
当然就上面那些肯定是不够的,下面来总结总结里面的细节问题!原创 2022-08-05 19:53:50 · 1656 阅读 · 0 评论 -
JVM堆和方法区是怎样的关系?
一个Java源文件中的类,接口,编译后产生一个字节码文件,而Java中的字节码需要数据支持,通常这种数据会很大,以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用,在动态链接的时候会用到运行时常量池。这回懂了吧,方法区在逻辑上是在堆里的,但是1.8之后在物理上各个虚拟机基本都给划分出来了,并且《Java虚拟机规范》也趋向于将两个区分开来(所以大家背面经的时候是分开背的,hhhhh,混淆的小伙伴们在看完这篇之后就懂一些了)它们不是一个概念,存放的位置是不同的。...原创 2022-08-16 21:26:38 · 2311 阅读 · 0 评论 -
JVM堆和方法区是怎样的关系?
一个Java源文件中的类,接口,编译后产生一个字节码文件,而Java中的字节码需要数据支持,通常这种数据会很大,以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用,在动态链接的时候会用到运行时常量池。这回懂了吧,方法区在逻辑上是在堆里的,但是1.8之后在物理上各个虚拟机基本都给划分出来了,并且《Java虚拟机规范》也趋向于将两个区分开来(所以大家背面经的时候是分开背的,hhhhh,混淆的小伙伴们在看完这篇之后就懂一些了)它们不是一个概念,存放的位置是不同的。...原创 2022-08-16 22:46:09 · 1894 阅读 · 0 评论 -
方法区、永久代、元空间
元空间是按照类加载器分配空间的,也就是说类加载器加载了一个类,元空间分配给这个类的空间其实是分配给的类加载器,不同的类加载器占用不同的空间,它们之间不共享类信息,如果程序中有大量的类加载器,而它们加载的类非常少,那么有可能会造成大量的空间浪费。元空间和永久代类似,都是对方法区的一个落地实现,他里面存储的数据比永久代纯粹很多,就是类的元数据。元空间的位置不存在于虚拟机中,而是在本地内存中。内存不够了,触发垃圾回收,那些不用的就会被回收,全清理了时,类加载器不使用了,被清理了,那么元空间内的数据被释放。....原创 2022-08-05 20:40:26 · 1361 阅读 · 0 评论 -
JVM中的堆的新生代、老年代、永久代
JVM堆内存 在物理上 分为三个区:伊甸园 eden:最初对象都分配到这里,与幸存区合称新生代幸存区 survivor:当伊甸园内存不足,回收后的幸存对象到这里,分成 from 和 to,采用标记复制算法老年代 old:当幸存区对象熬过几次回收(最多15次),晋升到老年代(幸存区内存不足或大对象会导致提前晋升)另外在逻辑上其实还存在一个元空间(1.8的,1.7是叫永久代)...原创 2022-08-16 18:06:14 · 2802 阅读 · 0 评论 -
JVM的三种常见GC:Minor GC、Major GC与Full GC
其实不分代完全可以,分代的唯一理由就是优化GC性能,如果没有分代,那所有的对象都在一个区域,当需要进行GC的时候就需要把所有的对象都进行遍历,GC的时候会暂停用户线程,那么这样的话,就非常消耗性能,然而大部分对象都是朝生夕死的,何不把活得久的朝生夕死的对象进行分代呢,这样的话,只需要对这些朝生夕死的对象进行回收就行了.总之,容易死的区域频繁回收,不容易死的区域减少回收.顾名思义,在新生代中,每次垃圾收集时都发现有大批对象死去,而每次回收后存活的少量对象,将会逐步晋升到老年代中存放。...原创 2022-08-16 18:18:21 · 11535 阅读 · 0 评论 -
什么是JIT编译器?
目前主流的商用Java虚拟机,比如HotSpot、OpenJ9等,内部都同时包含解释器与编译器。众所周知,解释器的设计和实现上比较简单,执行程序的效率又比编译器编译出来的程序慢。java一开始也是如此,但是它并没有不思进取,为了解决这个问题,后面JVM就开始使用HotSpot VM这个java虚拟机了。没错,JVM并不具体指代一种虚拟机,甚至当初有很多种JVM相互竞争,百家争鸣,当然随着时间的推移,逐渐统一了。而HotSpot VM的一大功能就是JIT。原创 2022-08-20 23:36:42 · 2526 阅读 · 2 评论 -
Java JVM运行时数据区(Run-Time Data Areas)
运行时数据区,是java虚拟机定义的在程序执行期间使用的各种运行时的数据区,通过JVM运行时数据区图例给大家展示的很详细,对JVM运行时数据区相关知识感兴趣的朋友跟随小编一起看看吧文章目录1、官网概括2、图例和思维导图3、方法区(Method Area)小总结:4、堆(Heap)小总结:5、Java虚拟机栈6、 栈帧(Stack Frame)7、程序计数器(The pc Register)8、本地方法栈(Native Method Stacks)1、官网概括引用官网说法:The Java Vi.转载 2022-04-29 09:34:25 · 354 阅读 · 0 评论 -
《深入理解 Java 虚拟机》读书笔记:晚期(运行期)优化
进行守护内联时,如果后续执行过程中,加载了导致继承关系发生变化的新类,则需要抛弃已经编译的代码,退回到解释状态执行,或者重新进行编译。实施分层编译后,C1、C2 编译器将会同时工作,用 C1 编译器获取更高的编译速度,用 C2 编译器获取更好的编译质量,解释执行时也无须再承担收集性能监控信息的任务。默认设置下,无论是方法调用产生的即时编译请求,还是 OSR 编译请求,虚拟机在代码编译还未完成之前,仍会按照解释方式继续执行,而编译动作则在后台的编译线程中进行。被多次执行的循环体成为热点代码时,所触发的编译。转载 2022-08-20 23:39:46 · 258 阅读 · 0 评论