JVM
文章平均质量分 58
大后生大大大
加油!加油!加油!
展开
-
JVM性能监控工具 - jcmd
jcmd,它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。比如:用它来导出堆、内存的使用情况、查看java进程、导出线程信息、执行GC、JVM运行时间等。原创 2021-06-19 17:12:45 · 357 阅读 · 0 评论 -
JVM性能监控工具 - jstack
jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。原创 2021-06-19 16:20:15 · 296 阅读 · 0 评论 -
JVM性能监控工具 - jhat
jhat(JVM Heap Analysis Tool)jdk自带的堆分析工具,与jmap搭配使用,用于分析jmap生成的heap dump文件。jhat内置一个微型的http/html原创 2021-06-19 15:38:43 · 523 阅读 · 0 评论 -
JVM性能监控工具 - jmap
jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中的对象的原创 2021-06-19 14:08:09 · 759 阅读 · 0 评论 -
JVM性能监控工具 - jinfo
jinfo(Configuration Info For Java),查看虚拟机配置的参数,也可以用于调整虚拟机的配置参数。在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。而原创 2021-06-19 13:16:48 · 207 阅读 · 0 评论 -
JVM性能监控工具 - jstat
Jstat全称JVM Statistics Monitoring Tool,用于监视虚拟机各种运行状态信息的命令工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据原创 2021-06-19 00:05:44 · 208 阅读 · 0 评论 -
JVM性能监控工具 - jps
JPS全称为Javaprocess Status。通过jps -help能看到jps支持的参数,如下:[root@iZwz96yphgzn3atc5wa1b1Z ~]# jps -hlepillegal argument: -hlepusage: jps [-help] jps [-q] [-mlvV] [<hostid>]Definitions: <hostid>: <hostname>[:<port>].原创 2021-06-18 23:38:00 · 351 阅读 · 0 评论 -
Stop The World
Stop The World简称STW,指的是GC事件过程中,会产生应用程序的停顿。停顿产生时这个应用程序线程都会被暂停,没有任何响应,有点卡死的感觉,这个停顿cheng'we原创 2021-06-17 18:24:46 · 100 阅读 · 0 评论 -
内存溢出和内存泄漏
内存溢出(OOM) 内存溢出相对于内存泄漏来说,尽管容理解,dan'shi 内存泄漏原创 2021-06-17 18:12:38 · 280 阅读 · 0 评论 -
System.gc( )的理解
在默认情况下,通过System.gc( )或者Runtime.getRuntime( ).gc( )的调用,会显示出发Full GC,同时对lao'nian原创 2021-06-17 17:27:20 · 1685 阅读 · 0 评论 -
垃圾回收相关算法
标记阶段:对象是否存活在堆里存放着所有的java对象,在GC执行垃圾回收之前,首先需要区分哪些对象是否存活,哪些对象已经死亡。只有被标记已经死亡的对象,GC才会在执行垃圾回收的释放掉其占用的额内存空间,因此这个过程我们称之为垃圾标记阶段。那么在jvm中如何标记一个对象已经死亡呢?简单来说,当一个对象已经不再被任何存活的对象引用时,就宣判该对象已经死亡。判断一个对象是否存活一般有两种方式:引用计数算法、可达性分析算法引用计数算法(Reference Counting) 对每一个对象保存一个整型的引用原创 2021-06-14 20:56:26 · 1201 阅读 · 2 评论 -
垃圾回收概述
什么是垃圾?垃圾是指在运行程序中没有任何指针指向的对象,这个对象是需要被回收的垃圾 如果要是不及时对内存中的垃圾进行清理,那么这些垃圾对象所占用的内存空间会一直保留到应用程序结束,被保留的空间无法被其他对象使用。甚至于可能导致内存溢出为什么需要GC?对于高级语言来说,一个基本的认知是如果不进行垃圾回收,内存迟早都会被消耗完,因为不断地分配内存空间而不进行回收,就好像不停的生产生活垃圾而从来不打扫一样 除了释放没用的对象,垃圾回收也可以清除内存里的记录碎片。碎片整理将占用的堆内存移动到堆的.原创 2021-06-10 22:30:47 · 253 阅读 · 3 评论 -
StringTable
String的基本特性String:字符串,使用" "引起来表示 String声明为final的,不能被继承 String实现了Serializable接口,表示字符串是支持序列化的。实现了Comparable接口,表示String可以比较大小 String在jdk8及以前内部定义了final char[ ] value用于存储字符串数据。jdk9时改成byte[ ] String代表不可变的字符序列。简称:不可变性 当对字符串重新赋值,需要重写指定内存区域赋值,不能使用原有的value进行赋原创 2021-05-22 13:44:45 · 292 阅读 · 1 评论 -
执行引擎(Execution Engine)- 执行引擎概述
执行引擎概述执行引擎是Java虚拟机核心组件之一 “虚拟机”相当于一个“物理机”的概念,这两种机器都有代码执行的能力,其区别是物理机的执行引擎是建立在处理器、缓存、指令集和操作系统上的,而虚拟机的执行引擎是由软件自行实现的,因此可以不受物理条件的制约的指定指令集与执行引擎的结构体系,能够执行那些不被支持的指令格式 JVM的主要任务是负责装载字节码到其内部,但字节码并不能直接运行在操作系统上,因此字节码指令非等价于本地机器的指令,内部包含的仅仅只是一些能够被JVM所识别的字节码指令、符号表,以及一些其原创 2021-05-20 10:21:21 · 801 阅读 · 0 评论 -
直接内存(Derect Memory)
直接内存概述不是虚拟机运行时数据区的一部分,也不是《Java虚拟机规范》中定义的内存区域 直接内存是在Java堆外的、直接向系统申请的内存区域 来源于NIO,通过DirectByteBuffer操作的Native内存 通常,访问直接内存的速度会优于Java堆。即:读写性能高: 因此,处于性能考虑,读写频繁的场合可以考虑只用直接内存 Java的IO库允许Java程序使用直接内存,用于数据缓冲区 也有可能导致OutOfMemoryError:Direct buffer memory异常.原创 2021-05-20 09:36:09 · 355 阅读 · 0 评论 -
对象的内存布局
对象的内存布局对象头(Head) 运行时元数据:Hash值(HashCode)、GC分代年龄、锁状态标志、线程只有的锁、偏向线程ID、偏向时间戳 类型指针:指向元数据InstanceClass,确定该对象所属的类型 如果创建的数组,还需要记录数组的长度 实例数据(Instance Data):对象真正存储的有效信息,包括代码汇总定义的各种类型的字段(包括从父类继承下来的和本身拥有的字段) 相同宽度的字段被分配到一起、父类中定义的变量会出现在子类之前、如果CompactFields参数原创 2021-05-20 00:40:51 · 97 阅读 · 0 评论 -
创建对象步骤
创建对象步骤1.判断对象对应的类是否加载、链接、初始化虚拟机遇到new指令,首先去检查这个指令的参数能否在Metaspace的常量池中找到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析、初始化。(即判断类元信息是否存在)如果没有,那么在双亲委派的模式下使用当前类的加载器以ClassLoader+包名+类名为key进行查找对应的.class文件。如果没有找到该文件,则抛出ClassNotFindException异常,如果找到则进行类加载,并生成对应的Class类对象。2...原创 2021-05-19 23:02:08 · 143 阅读 · 0 评论 -
运行时数据区-方法区(Method Area)- 方法区的垃圾回收
方法区的垃圾回收有些人认为方法区(如Hotspot虚拟机中的元空间或者永久代)是没有垃圾回收的,其实不然。在《Java虚拟机规范》对方法区的约束非常宽松的,提到过可以不要求虚拟机在方法区中实现垃圾收集。实事上也确实有没有实现或者未能完整实现方法区类型卸载的收集器存在的(如JDK11时期ZGC收集器就不支持类型卸载)。一般来说这个区域的回收效果比较难令人满意,尤其是类型卸载,条件相当苛刻。但是这部分区域的回收有时是必要的。以前sun公司的Bug列表中,曾出现过若干个严重的Bug就是由于低版本的Hots原创 2021-05-18 22:23:53 · 137 阅读 · 0 评论 -
运行时数据区-方法区(Method Area)- 方法区的演变细节
方法区的演变细节首先明确:只有Hotspot中才有永久代。BEA、JRockit、IBM的J9等来说,是不存在永久代的概念的。原则上如何实现方法区属于虚拟机实现细节,不受《Java虚拟机规范》约束,不做统一要求 Hotspot中方法区的变化 jdk1.6及以前:有永久代,静态变量存放在永久代上 jdk1.7:有永久代,但是已经逐步“去永久代”,字符串常量池、静态变量移除,保存在堆中 jdk1.8及之后:无永久代,类型信息、字段、方法、常量保存在本地内存的元空间,但是字符串常量池、静态变量仍在原创 2021-05-17 23:29:48 · 178 阅读 · 0 评论 -
运行时数据区-方法区(Method Area)- 运行时常量池 vs 常量池
运行时常量池 vs 常量池方法区,内部包含了运行时常量池 字节码文件,内部包含了常量池 要弄清楚运行时常量池,需要弄清楚ClassFile,因为加载类的信息都在方法区 要弄清楚方法区的运行时常量池,需要理解ClassFile中的常量池一个有效的字节码文件中包含了类的版本信息、字段、方法以及接口描述信息外,还包含一项重要的信息,那就是常量池表(Constant Pool Table),包括各种字面量和对类型、域和方法的符号引用为什么需要常量池?一个Java源文件中的类、接口、编译后产.原创 2021-05-17 22:00:18 · 182 阅读 · 3 评论 -
运行时数据区-方法区(Method Area)- 方法区内部结构
运行时数据区-方法区(Method Area)- 方法区内部结构方法区(Method Area)存储了什么?《深入理解Java虚拟机》书中方法区(Method Area)存储内容描述如下:它用于存储已经被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等类型信息每个类加载的类型(类class、接口interface、枚举enum、注解annotation),JVM必须在方法区中存储以下类型信息:这个类型的完整的有效类名(类全名=包名.类名) 这个类型直接父类的原创 2021-05-15 16:13:05 · 281 阅读 · 0 评论 -
运行时数据区-方法区(Method Area)- Hotspot中方法区的演进
运行时数据区-方法区(Method Area)- Hotspot中方法区的演进在jdk7以及之前,习惯上吧方法区称为永久代。jdk8开始,使用元空间取代了永久代 本质上方法区和元空间并不等价,仅是Hotspot而言的。《Java虚拟机规范》对如何实现方法区不做同意要求。 现在看来,当年使用永久代不是很好的方式,导致Java程序更加容易引起OOM(超出-XX:MaxPermSize设置的上限) 而到jdk8,终于完全放弃永久代的概念,改用本地内存实现的元空间(Matespace)来代替 元空间原创 2021-05-14 00:29:54 · 172 阅读 · 0 评论 -
运行时数据区-方法区(Method Area)
运行时数据区-方法区(Method Area)每个线程私有空间 虚拟机栈、本地方法栈、程序计数器 线程间共享 堆、元空间 会报异常、会发生GC 堆、栈 会报异常、不会发生GC 虚拟机栈、本地方法区 不会报异常、不会发生GC 程序计数器 堆、栈、方法区交互关系...原创 2021-05-13 23:11:04 · 80 阅读 · 0 评论 -
运行时数据区-堆(Heap)- 堆空间是分配实例对象的唯一选择吗?
运行时数据区-堆(Heap)- 堆空间是分配实例对象的唯一选择吗?在《深入理解Java虚拟机》中关于Java堆内存又这么一段描述:随着JIT编译器的发展与逃逸分析逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙变化,所有对象都分配到堆上渐渐变得不那么“绝对”了在Java虚拟机中,对象是在Java堆中分配内存的,这是一个普遍的常识。但是,有一种特俗情况,那就是如果经过逃逸分析(Escape Analysis)后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。这样就无需堆上分配内原创 2021-05-12 21:42:38 · 91 阅读 · 0 评论 -
运行时数据区-堆(Heap)- 堆空间参数设置
运行时数据区-堆(Heap)- 堆空间参数设置Oracle参数地址(JDK1.8):https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html-XX:+PrintFlagsInitial:查看所有参数的默认值 -XX:PrintFlagsFinal:查看所有参数的最终值(可能会存在修改,不是初始值) -Xms:初始堆空间内存(默认占物理内存的1/64) -Xmx:最大堆空间内存(默认占物理内存的1/4) -Xmn:原创 2021-05-12 00:00:59 · 214 阅读 · 0 评论 -
运行时数据区-堆(Heap)- 为对象分内存:TLAB
运行时数据区-堆(Heap)- 为对象分内存:TLAB为什么有TLAB(Thread Local Allocation Buffer)?对区域是线程共享的,任何线程可以访问对区域中的共享数据 由于对象的实例的创建在JVM中很频繁,因此在并发环境下从堆区中划分内存空间是线程不安全的 为避免多个线程操作同一个内存地址,则需要使用加锁机制,进而影响分配速度什么是TLAB?从内存模型而不是从垃圾收集的角度,对Eden区继续进行划分,JVM为每个线程分配了一个私有的缓冲区,它包含在Eden空间内原创 2021-05-11 23:25:40 · 148 阅读 · 0 评论 -
运行时数据区-堆(Heap)- Minor GC、Major GC与Full GC
Minor GC、Major GC 与 Full GCJVM在GC时,并不是都对三个内存(新生代、老年代、方法区)区域一起进行垃圾回收的,大部分时候回收的都是指新生代针对HotSpot VM的实现,它里面按照回收区域又分为两大类:部分收集(Partial GC)、整堆收集(Full GC) 部分收集:不是完整收集整个Java堆的垃圾收集。其中又分为: 新生代收集(Minor GC / Young GC):只是新生代的垃圾收集 老年代收集(Major GC / Old原创 2021-05-10 23:39:19 · 285 阅读 · 0 评论 -
运行时数据区-堆(Heap)- 年轻代与老年代
年轻代与老年代存储咋在JVM中的Java对象可以被划分为两类: 一类是生命周期较短的瞬时对象,这类对象的创建和消亡非常迅速 另一类对象的生命周期确非常长,在某种极端的情况下还能够与JVM生命周期保持一致 Java堆区进一步细分的话,可以划分为年轻代(YoungGen)和老年代(OldGen) 其中年轻代又可以划分为Eden空间和Survivor0空间和Survivor1空间(有时也叫做from区和to区) 配置新生代于老年代在对结构的占比: 默认-XX: NewRatio=2,表示原创 2021-05-08 21:58:07 · 294 阅读 · 0 评论 -
运行时数据区-堆(Heap)
堆(Heap)一个JVM虚拟机实例只存在一个堆内存,堆也是Java内存管理的核心区域 Java堆区存在JVM启动的时候被创建,其空间大小也就确定了。是JVM管理的最大的一块内存空间 堆的内存空间是可以调节的 Java虚拟机规范规定,堆可以处于物理上不连续的空间,但是在逻辑上它应该视为连续的 所有的线程共享Java堆,这里我们还可以为线程分配私有的缓冲区(Thread Local Allocation Buffer,TLAB) Java虚拟机规范中堆Java堆的描述是:所有的对象实例以及原创 2021-05-07 01:31:12 · 339 阅读 · 2 评论 -
运行时数据区-本地方法栈(Native Method stack)
本地方法栈(Native Method stack)Java虚拟机栈式用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用 本地方法栈也是线程私有的 允许被实现成固定或者是可以动态扩展的内存大小(在溢出方面也是相同的) 如果线程请求分配的栈容量超过本地方法栈允许的容量,Java虚拟机将会抛出一个StackOverflowError异常 如果本地方法栈可以动态扩展,并且尝试扩展时无法申请到足够的内存或者在创建新的线程时没有足够的内存去创建本地方法栈,那么Java虚拟机将会抛出一个O原创 2021-04-29 00:38:56 · 101 阅读 · 0 评论 -
本地方法库和本地方法接口
本地方法库和本地方法接口什么是本地方法?简单的讲,一个Native Method就是一个Java调用非Java代码的接口。一个Native Method是这样一个Java方法:该方法实现又非Java语言实现,比如C。这个特性并非Java所特有,很多语言都有这一机制,比如C++中,你可以使用extend “c” 告知c++编译器去调用一个c函数。在定义一个native method时,并不是提供具体的实现(有些像定义一个Java interface),因为具体实现由非Java语言在外米阿.原创 2021-04-28 22:34:45 · 614 阅读 · 0 评论 -
运行时数据区-虚拟机栈-方法返回地址(Return Address)
方法返回地址(Return Address)存放调用该方法的PC寄存器的值 一个方法结束,有两种方式: 正常执行完成 出现未处理的异常,非正常退出 无论通过哪种方法退出,在方法退出后都返回到该方法调用的位置。方法正常退出时,调用者的PC寄存器的值作为返回地址,即调用该方法的指令的下一条指令的地址。而异常退出的,返回地址是要通过异常表来确定,栈帧中一般不会保存这部分信息当一个方法开始执行后,只有两种方式可以退出这个方法执行引擎遇到任意一个返回字节码的指令(return),会有返回.原创 2021-04-27 00:35:24 · 733 阅读 · 0 评论 -
运行时数据区-虚拟机栈-动态链接(Dynamic Linking)
动态链接(Dynamic Linking)(指向运行时常量池的方法的引用)每一个栈帧内部都包含一个指向运行时常量池中该帧所属方法的引用。包含这个引用的目的是为了支持当前方法的代码能实现动态链接(Dynamic Linking)。 在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在class文件的常量池里。比如:描述一个方法调用另外一个方法时,是通过常量池中指向方法的符号引用来表示的,那么动态链接的作用就是为了将这些符号引用转换为调用原创 2021-04-26 23:05:25 · 469 阅读 · 2 评论 -
运行时数据区-虚拟机栈-操作数栈(Operand Stack)
操作数栈(OperandStack)每一个独立的栈帧中除了包含局部变量表,还包含了一个后进先出(Last-In-Last-Out)的操作数栈,也可以称之为表达式栈(Expression Stack) 操作数栈,在方法执行的过程中,根据字节码指令,往栈中写入数据或者提取数据,即入栈(push)、出栈(pop) 某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈,使用后再把结果压入栈 比如:执行复制、交换、求和等操作 如果被调用的方法有返回值的话,其返回值将会被压入当前的操作数栈.原创 2021-04-26 02:02:02 · 251 阅读 · 0 评论 -
运行时数据区-虚拟机栈-局部变量表
栈中存储什么?每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在 在这个线程执行的时候每个方法各自对应一个栈帧 栈帧是一块内存区块,是一个数据集,维系着方法在调用的过程中各种数据信息 JVM直接对Java栈的操作只有两个,就是对栈的压栈和出栈,遵循“先进后出”/“后进先出”原则 在一条活动的线程中,一个时间点只会有一个活动的栈。即只有当前正在执行的方法的栈帧(栈顶栈帧)是有效的,这个栈被称为当前栈帧 执行引擎运行所有字节码指令只对当前栈帧进行操作 如果该方法调用了原创 2021-04-26 00:01:46 · 201 阅读 · 0 评论 -
类加载器
虚拟机自带的加载器启动类加载器(引导类加载器,Bootstrap ClassLoader)这个类加载器使用c/c++语言实现,镶嵌在JVM内部 它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar、recourses.jar、sun.boot.class.path路径下的内容),用于提供JVM自身需要的类 并不继承自java.lang.ClassLoader,没有父类加载器 加载扩展类(ExtClassLoader)和应用类加载器(AppClassLoader),并指定为原创 2021-04-26 00:01:10 · 90 阅读 · 0 评论 -
运行时数据区-虚拟机栈(概述)
虚拟机栈出现的背景由于跨平台设计,Java的指令是根据栈来设计的。不同平台CPU架构不同,所以不能设计基于寄存器架构优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令内存中的栈与堆栈式运行时的单位,而堆是存储的单位。即栈解决的是程序运行时的问题,程序如何执行,或者说如何处理数据。堆解决的是数据存储的问题,即数据怎么放,放哪里虚拟机栈基本内容 1. Java虚拟机栈是什么? Java虚拟机(Java Virual Mach...原创 2021-04-25 00:11:38 · 183 阅读 · 0 评论 -
运行时数据区-程序计数器(PC寄存器)
PC寄存器(PC Register)JVM中的程序寄存器(Program Counter Register)中,Register的 命名起源于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能运行。这里,并非广义上所指的物理寄存器,或许将其翻译为PC计时器(或者指令计数器)会更加贴切(也称为程序钩子)。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。作用PC寄存器是用来存储指向下一条指令的地址,也即将执行行的指令代码。由执行引擎读取下一条指令。 ...原创 2021-04-25 00:11:14 · 272 阅读 · 0 评论 -
运行时数据区
内存是非常重要的系统资源,是硬盘和cpu的中间仓库和桥梁,承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程中内存的申请、分配、管理的策略,保证JVM高效稳定运行。不同的JVM对于内存的划分和管理机制存在着部分差异。Java虚拟机定义了若干种程序运行期间会使用的运行时数据区,其中一些会随着虚拟机的创建而创建,随着虚拟机的退出而销毁。另外一些则是与线程一一对应,这些与线程对应的数据区会随着线程开始而创建,随着线程结束而销毁。每个线程:独立包括程序计数器、栈、本地栈线程间共享原创 2021-04-25 00:09:50 · 74 阅读 · 0 评论 -
判断两个class对象是否是同一个的两个必要条件
判断两个class对象是否是同一个的两个必要条件类的完整类名是否一致,包括包名 加载这个类的ClassLoader(指ClassLoader实例对象)必须相同换句话说,在JVM中,即使两个类对象(class对象)来源同一个Class文件,被同一个虚拟机所加载,但只要加载它们的ClassLoader实例对象不一样,那么这两个对象也是不相同的...原创 2021-04-25 00:09:19 · 646 阅读 · 0 评论