JVM
文章平均质量分 87
JVM
小鲁蛋儿
莫道桑榆晚,为霞尚满天。
展开
-
深入理解JVM(二十一)类的加载过程(类的声明周期)详解
)初始化阶段的重要工作是执行类的初始化方法:()方法。原创 2022-09-12 12:33:05 · 181 阅读 · 0 评论 -
深入理解JVM(二十)字节码指令集与解析举例
int a = 5;int b = 6;}}注意:常量入栈指令中的n和局部变量压栈指令中的n不一样,本次的n代表数值或者对象,而不是局部变量表中的下标。原创 2022-09-10 17:28:48 · 1341 阅读 · 0 评论 -
深入理解JVM(十九)使用javap指令解析Class文件
1、通过javap命令可以查看一个java 类反汇编得到的Class文件版本号、常量池、访问标识、 变量表、指令代码行号表等信息。不显示类索引、父类索引、接口索引集合、()、 ()等结构2、通过对前面例子代码反汇编文件的简单分析,可以发现,一个方法的执行通常会涉及下面几块内存的操作java栈中:局部变量表、操作数栈。java堆:通过对象的地址引用去操作。常量池其他如帧数据区、方法区的剩余部分等情况,测试中没有显示出来,这里说明一下。原创 2022-09-09 12:25:04 · 512 阅读 · 0 评论 -
深入理解JVM(十八)Class文件结构
Class文件其实就是对类的整体描述。类有哪些字段?有哪些方法?类的全限定名?类的父类是谁?类实现的接口有哪些?方法中具体的方法体是什么?类的访问权限和修饰符等Class文件中有一块非常重要的内容就是常量池,通过上面的分析可以得知,常量池中存储的符号引用,其他描述的地方引用常量池中的符号引用,最后都定位到字面量(字符串、基本数据类型)小结随着Java平台的不断发展,在将来Class文件的内容也一定会做进一步的扩充,但是其基本的格式和结构不会做重大调整。原创 2022-09-09 11:22:08 · 131 阅读 · 0 评论 -
深入理解JVM(十八)GC日志分析
GC、Full GC: GC的类型,GC只在新生代上进行,Full GC包括永久代,新生代, 老年代。ParOldGen:使用了Parallel Old并行垃圾收集器的老年代Gc前后大小的变化。但是如果想查看更详细的信息, 比如新生代在GC前后的变化或者老年代在GC前后的变化等,real :GC从开始到结束的时间,包括其他进程占用时间片的实际时间。Times: user: 指的是垃圾收集器花费的所有CPU时间,15267K->13850K:堆在GC前的大小和GC后的大小。58880K:现在的堆大小。原创 2022-09-09 09:20:38 · 475 阅读 · 0 评论 -
深入理解JVM(十七)垃圾回收器
垃圾收集机制是Java的招牌能力,极大地提高了开发效率。这当然也是面试的热点。那么,Java常见的垃圾收集器有哪些?这种垃圾收集器大家了解,现在已经不用串行的了。而且在限定单核cpu才可以用。现在都不是单核的了。对于交互较强的应用而言,这种垃圾收集器是不能接受的。一般在Javaweb应用程序中是不会采用串行垃圾收集器的。截止JDK 1.8,一共有7款不同的垃圾收集器。每一款不同的垃圾收集器都有不同的特点,在具体使用的时候,需要根据具体的情况选用不同的垃圾收集器。原创 2022-09-08 11:06:26 · 727 阅读 · 0 评论 -
深入理解JVM(十五)垃圾回收相关概念
在默认情况下,通过或者的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。然而调用附带一个免责声明,无法保证对垃圾收集器的调用(无法保证马上触发GC)。JVM实现者可以通过system.gc()调用来决定JVM的GC行为。而一般情况下,垃圾回收应该是自动进行的,无须手动触发,否则就太过于麻烦了。在一些特殊情况下,如我们正在编写一个性能基准,我们可以在运行之间调用System.gc()。原创 2022-09-07 09:38:10 · 319 阅读 · 0 评论 -
深入理解JVM(十四)垃圾回收相关算法
在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们可以称为阶段。那么在JVM中究竟是如何标记一个死亡对象呢?简单来说,当一个对象已经不再被任何的存活对象继续引用时,就可以宣判为已经死亡。和。原创 2022-09-06 15:02:33 · 151 阅读 · 0 评论 -
深入理解JVM(十三)字符串常量池(String Table)
将这个字符串对象尝试放入串池。如果字符串常量池中有,则并不会放入。返回已有的串池中的对象的地址如果没有,会把此对象复制一份,放入串池,并返回串池中的对象地址将这个字符串对象尝试放入串池。如果字符串常量池中有,则并不会放入。返回已有的串池中的对象的地址如果没有,则会把对象的引用地址复制一份,放入串池,并返回串池中的引用地址//在上一行代码执行完以后,字符串常量池中并没有"ab"//jdk6中:在串池中创建一个字符串"ab"原创 2022-09-05 19:53:15 · 783 阅读 · 0 评论 -
深入理解JVM(十二)执行引擎
解释器:当Java虚拟机启动时会根据预定义的规范对字节码采用逐行解释的方式执行,将每条字节码文件中的内容“翻译”为对应平台的本地机器指令执行。JIT (Just In Time Compiler)编译器(即时编译器):就是虚拟机将源代码直接编译成和本地机器平台相关的机器语言。一般来讲,JIT编译出来的机器码性能比解释器高。C2编译器启动时长比C1编译器慢,系统稳定执行以后,C2编译器执行速度远远快于C1编译器。原创 2022-09-05 17:31:09 · 117 阅读 · 0 评论 -
深入理解JVM(十一)直接内存
不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域。直接内存是在Java堆外的、直接向系统申请的内存区间。来源于,通过存在堆中的DirectByteBuffer操作Native内存。通常,访问直接内存的速度会优于Java堆。即读写性能高。查看进程id直接占用了 1G 的本地内存释放后,Java程序的内存占用明显减少。原创 2022-09-05 10:35:26 · 251 阅读 · 0 评论 -
深入理解JVM(十)对象的实例化内存布局与访问定位
虚拟机遇到一条new指令,首先去检查这个指令的参数能否在Metaspace的常量池中定位到一个类的,并且检查这个符号引用代表的类是否已经被加载,解析和初始化。(即判断类元信息是否存在)。如果该类没有加载,那么在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + 类名为key进行查找对应的.class文件,如果没有找到文件,则抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成对应的 Class 类对象。原创 2022-09-04 19:40:51 · 109 阅读 · 0 评论 -
深入理解JVM(九)方法区
常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要 执行的类名、方法名、参数类型、字面量等信息。原创 2022-09-04 18:35:05 · 366 阅读 · 0 评论 -
深入理解JVM(八)堆
针对于幸存者s0,s1区的总结:复制之后有交换,谁空谁是to关于垃圾回收:频繁在新生区收集,很少在养老区收集, 几乎不在永久区/元空间收集从内存模型而不是垃圾收集的角度,对Eden区域继续进行划分,JVM为每个线程分配了一个私有缓存区域,它包含在Eden空间内。多线程同时分配内存时,使用TLAB可以避免一系列的非线程安全问题,同时还能够提升内存分配的吞吐量,因此我们可以将这种内存分配方式称之为快速分配策略。据我所知所有OpenJDK衍生出来的JVM都提供了TLAB的设计。原创 2022-09-03 14:19:20 · 443 阅读 · 0 评论 -
深入理解JVM(七)本地方法栈
因为Java虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方式、数据结构等。它的具体做法是本地方法栈中登记本地方法,在执行引擎(Execution Engine)执行时加载本地方法库。Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用。如果JVM产品不打算支持native方法,也可以无需实现本地方法栈。在Hotspot JVM中,直接将本地方法栈和虚拟机栈合二为一。本地方法可以通过本地方法接口来访问虚拟机内部的运行时数据区。本地方法栈,也是线程私有的。原创 2022-09-02 19:21:55 · 173 阅读 · 0 评论 -
深入理解JVM(六)本地方法接口
简单地讲,一个Native Method是一个Java调用非Java代码的接囗。一个Native Method是这样一个Java方法:该方法的实现由非Java语言实现,比如C。这个特征并非Java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去 调用一个C的函数。原创 2022-09-02 19:13:58 · 233 阅读 · 0 评论 -
深入理解JVM(五)虚拟机栈
程序试图访问或修改一个属性或调用一个方法,这个属性或方法,你没有权限访问。一般的,这个会引起编译器异常。这个错误如果发生在运行时,就说明一个类发生了不兼容的改变。比如,你把应该有的jar包从工程中拿走了,或者Maven中存在jar包冲突。原创 2022-09-02 18:56:37 · 281 阅读 · 0 评论 -
深入理解JVM(四)程序计数器(PC寄存器)
JVM中的程序计数寄存器(Program Counter Register),Register的命名源于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。这里,并非是广义上所指的物理寄存器,或许将其翻译为PC计数器(或指令计数器)会更加贴切(也称为程序钩子),并且也不容易引起一些不必要的误会。。作用: PC寄存器用来存储指向下一条指令的地址,也就是即将要执 行的指令代码。由执行引擎读取下一条指令,并执行该指令。当前方法。...原创 2022-09-01 11:51:10 · 224 阅读 · 0 评论 -
深入理解JVM(三)运行时数据区概述及线程
当我们通过前面的:类的加载 --> 验证 --> 准备 --> 解析 --> 初始化,这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们的运行时数据区。比如大厨做饭,我们把大厨后面的东西(切好的菜,刀,调料), 比作是运行时数据区。而厨师可以类比于执行引擎,将通过准备的东西制作成精美的菜品。内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。.........原创 2022-09-01 11:09:27 · 97 阅读 · 0 评论 -
深入理解JVM(二)类加载子系统
在Java的日常应用程序开发中,类的加载几乎是由上述3种类加载器相互配合执行的,在必要时,我们还可以自定义类加载器,来定制类的加载方式。那为什么还需要自定义类加载器?隔离加载类修改类加载的方式扩展加载源防止源码泄露开发人员可以通过继承抽象类java.lang.ClassLoader类的方式,实现自己的类加载器,以满足一些特殊的需求。......原创 2022-09-01 10:41:34 · 127 阅读 · 0 评论 -
深入理解JVM(一)JVM与Java体系结构
由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。优点是跨平台, 指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令。.........原创 2022-08-31 18:14:54 · 254 阅读 · 0 评论