中小企业做网站,专门做餐饮装修的公司,广州响应式网站开发,微信公众号怎么推广和引流java虚拟机 流程#xff1a;helloworld.java----(javac编译)----helloworld.class-------(java运行)——JVM——机器码JVM功能 *解释和运行 *内存管理 *即时编译#xff08;跨平台-慢一点#xff09;jit #xff08;反复用到的代码 解释保存再内存里面#xff09;…java虚拟机 流程helloworld.java----(javac编译)----helloworld.class-------(java运行)——JVM——机器码JVM功能 *解释和运行 *内存管理 *即时编译跨平台-慢一点jit 反复用到的代码 解释保存再内存里面 jvm主要组成 *类加载器 *运行时数据区jvm管理的内存 *执行引擎即时编译器解释器垃圾回收器 字节码文件组成
工具notepad是不可以的 工具用 jclasslib 组成基本信息常量池字段方法属性
基本信息 1 magic魔数确认是字节码文件前缀固定0xcofe base 2主版本号 (-44就等于jdk)-可以确定运行jdk和编译的版本是否一致
常量池 避免重复内容的重复定义浪费空间 *常量池的数据都有一个编号 *字节码指令中提高编号引用常量池的过“符合引用”方法 JVM:堆栈方法区栈是线程用的后进先出执行完就会释放 *有多个栈帧组成对应着每次方法调用时所占的内存 *每个线程只能有一个活动栈帧对应正在执行的方法 递归会导致栈溢出一个线程一个栈一个方法一个栈帧 JVM调优 栈和栈帧
程序启动 在jvm的加载机制1将代码加载到 方法区类加载2栈启动mian主线程: 然后给线程的方法分配栈帧 new出来的对象放堆,方法执行完栈帧就会释放 1线程启动就会分配栈和程序计数器2执行方法就会右栈帧线程的栈帧是独立的 3方法执行完栈帧就会释放,线程执行完栈就释放程序计数器 *记录每个线程的执行到哪里-记录当前线程的状态-线程独有的多线程切换用的 *由字节码执行引擎修改里面的内容多线程的时候 操作系统的任务调度器 分配时间片
栈帧存的数据 1局部变量表int 1等 2操作数栈加减乘除操作时的数据空间计算完就释放 3动态链接、每个方法内存地址映射 元空间/方法区 4方法出口方法执行完 要继续执行main方法的下一个
堆new出来的对象---公共
栈线程放线程的--私有 栈里面的对象保证地址是指向堆的本地方法栈用native修饰的方法-底层是用C实现的--私有 Thread类的本地方法 System类的本地方法
方法区元空间常理静态变量类信息---公共 方法区的对象也是指向堆的 JDK诊断工具
*Java VisualVM是JDK自带的基本调优工具之一 *jdk自带诊断命令 *arthas(阿里巴巴)诊断工具 。可以快速点位cpu高代码 。可以快速点位锁代码 。线上运行代码反编译 JVM堆的组成 1. 新生代Young Generation新生代是堆的一部分用于存储新创建的对象。它又分为Eden区、Survivor区通常有两个。 - Eden区新创建的对象首先分配在Eden区。 - Survivor区当Eden区满时存活的对象会被移到Survivor区。Survivor区一般有两个分别称为From区和To区。存活的对象会在From区和To区之间进行复制经过多次垃圾回收后每次年龄1仍然存活的对象会被移动到老年代15岁/6 CMS。 2. 老年代Old Generation老年代用于存储长时间存活的对象。当对象经过多次垃圾回收后仍然存活它们会被移动到老年代。full GC老年代也回收对象年龄判断机制如果对象大于Survivor 50%会直接放老年代 3. 永久代Permanent Generation永久代用于存储类的元数据metadata和方法信息method information。在JDK 8之后永久代被元空间Metaspace所取代。元空间不再位于堆中而是位于本地内存中。 4. 堆外内存Off-Heap Memory堆外内存是指不受JVM堆管理的内存通常由本地方法直接分配和释放。堆外内存包括直接内存Direct Memory和本地内存Native Memory。 需要注意的是JVM的堆大小可以通过启动参数进行配置例如-Xmx和-Xms参数用于设置堆的最大和初始大小。堆的大小对于应用程序的性能和内存使用有重要影响需要根据具体应用场景进行合理配置。 堆-对象直接进入老年代
1,动态年龄判断survivor从小到大累加年龄超过空间的50%默认 后面的会直接晋升老年代
2 ,大对象直接接入 大对象就是需要大量连续内存空间的对象比如字符串、数组。 复制很耗性能 JVM参数XX:PretenureSizeThreshold 可以设置大 对象的大小如果对象超过设置大小会直接进入老年代不会进入年轻代这个参数只在 Serial 和ParNew两个收集器下 有效。比如设置JVM参数 -XX:PretenureSizeThreshold1000000 (单位是字节) -XX:UseSerialGC 再执行下上 面的第一 个程序会发现大对象直接进了老年代 为什么要这样呢原因 为了避免为大对象分配内存时的复制操作而降低效率。解决——加大Survivor区并用G1分代收集 3,老年代空间担保机制 From区和To区的作用如下 1. 存储存活对象在Minor GC过程中存活的对象会被移动到Survivor区的From区。 2. 进行对象复制在下一次Minor GC之前存活的对象会从From区复制到To区。 3. 清空From区复制完成后From区会被清空为下一次Minor GC做准备。 4. 交换From区和To区在下一次Minor GC时From区和To区会互换角色即From区变为To区To区变为From区。 通过交替使用From区和To区Survivor区可以实现对象的复制和清理以进行有效的垃圾回收。这种复制算法被称为标记-复制Mark and Copy算法它可以有效地处理新生代中的对象并减少内存碎片化的问题。 需要注意的是Survivor区的大小可以通过JVM参数进行调整以适应不同应用程序的需求。一般来说Survivor区的大小应该合理设置避免过小导致频繁的对象复制或过大导致浪费内存空间。 垃圾回收 Minor GC 和 Full GC 垃圾回收会导致 stw(Stop the World)这个系统停顿 为什么要这样设计不停止用户线程里面对象就会不断变化实现简单 JVM的可达性分析
JVM的可达性分析Reachability Analysis是垃圾回收的一种核心算法用于确定哪些对象是可达的reachable或不可达的unreachable从而确定哪些对象应该被回收。 可达性分析的基本原理是从一组称为GC Roots的根对象开始通过遍历对象引用链标记所有与根对象直接或间接相连的对象为可达对象。而未被标记的对象则被认为是不可达的即无法通过任何引用链访问到的对象。这些不可达对象将被垃圾回收器识别并回收释放其占用的内存空间。 GC Roots包括以下几种类型的对象 1. 虚拟机栈VM Stack中的引用对象。 2. 方法区Method Area中类静态属性引用的对象。 3. 方法区中常量引用的对象。 4. 本地方法栈Native Method Stack中JNI引用的对象。 通过从GC Roots出发进行可达性分析JVM可以确定哪些对象是活动的即仍然被引用和使用的对象而哪些对象是不再使用的可以被回收的对象。 可达性分析是现代垃圾回收器中常用的算法它具有高效、准确的特点并能够处理复杂的对象引用关系。通过可达性分析JVM可以自动管理内存释放不再使用的对象从而提高系统的性能和资源利用率。
Minor GC
Minor GCMinor Garbage Collection是Java虚拟机JVM中的一种垃圾回收操作主要针对新生代进行回收。新生代是Java堆内存中的一部分用于存储新创建的对象。Minor GC的目标是清理新生代中的无用对象以释放内存空间。 在Minor GC过程中垃圾回收器会扫描新生代中的对象并标记那些仍然存活的对象。然后它会将存活的对象复制到Survivor区通常是From区同时清理掉无用的对象。在复制过程中存活的对象会被移动到Survivor区的To区。最后From区会被清空为下一次垃圾回收做准备。 Minor GC通常发生在新生代中的Eden区新对象的分配区域空间不足时。当Eden区满了之后会触发Minor GC来回收无用的对象以便为新对象腾出空间。通常情况下大部分对象在新生代中很快被回收只有少部分对象会进入老年代Old Generation。 相比于Full GCFull Garbage CollectionMinor GC的开销较小回收的对象数量也较少。因此Minor GC的执行时间通常较短对应用程序的停顿时间影响较小。它是Java堆内存中垃圾回收的常见操作之一用于保证新生代的内存空间的有效利用。 Full GC
Full GCFull Garbage Collection是Java虚拟机JVM中垃圾回收的一种操作它是对整个堆内存进行回收的过程。Full GC会清理整个堆内存中的所有对象包括年轻代和老年代。 Full GC通常是在进行一次完整的垃圾回收之前执行的目的是回收所有不再被引用的对象释放内存空间。Full GC的执行会导致应用程序的停顿因为在此期间所有的应用线程都会被暂停直到垃圾回收完成。 Full GC通常发生在以下情况下 1. 当堆内存空间不足时如老年代太多无法分配新的对象时会触发Full GC来回收内存。 2. 当执行System.gc()方法或者调用Runtime.getRuntime().gc()方法时可能会触发Full GC。 3. 当永久代Permanent Generation空间不足时在JDK 8及之前的版本中会触发Full GC来回收永久代。 Full GC的执行时间通常比部分垃圾回收如年轻代的Minor GC更长并且会导致较长的停顿时间。因此对于性能敏感的应用程序需要合理配置堆内存大小以减少Full GC的频率和影响。 总之Full GC是Java虚拟机中对整个堆内存进行的垃圾回收操作它会清理整个堆内存中的所有对象包括年轻代和老年代通常会导致较长的停顿时间。 JVM中常见的垃圾回收算法和策略包括以下几种 1. 标记-清除算法Mark and Sweep该算法分为两个阶段首先标记所有活动对象然后清除未标记的对象。但是标记-清除算法会产生内存碎片可能会导致内存分配效率降低。 2. 复制算法Copying该算法将堆内存划分为两个相等大小的区域每次只使用其中一个区域。当一个区域满时将存活的对象复制到另一个区域然后清除当前区域中的所有对象。复制算法消耗的时间较短但会浪费一部分内存空间。 3. 标记-压缩算法Mark and Compact该算法首先标记所有活动对象然后将活动对象向一端移动最后清理掉边界以外的内存空间。标记-压缩算法消除了内存碎片但可能会导致对象移动的开销较大。 4. 分代收集算法Generational Collection该算法根据对象的生命周期将堆内存划分为不同的代Generation如新生代Young Generation和老年代Old Generation。新生代中的对象生命周期较短采用复制算法而老年代中的对象生命周期较长采用标记-压缩算法。 5. 并发标记清除算法Concurrent Mark and Sweep该算法允许垃圾回收器与应用程序并发执行减少停顿时间。它通过在标记和清除阶段之间允许应用程序继续运行来提高性能。 6. G1收集器Garbage-First CollectorG1收集器是一种面向服务端应用的垃圾回收器它将堆内存划分为多个大小相等的区域Region通过并发标记、并发清除和并发整理来实现高效的垃圾回收。 这些垃圾回收算法和策略的选择取决于应用程序的性能需求和内存特点。JVM根据实际情况自动选择适当的垃圾回收器和算法来管理内存。 垃圾收集器
G1Garbage First收集器是Java虚拟机JVM中的一种垃圾收集器。它在JDK 7u4版本中首次引入并在JDK 9及以后的版本中成为默认的垃圾收集器。G1收集器采用了分代收集和并发标记整理的方式旨在提供可预测的停顿时间和高吞吐量的垃圾收集性能。 G1收集器的主要特点和优势包括 1. 分代收集G1收集器将堆内存划分为多个大小相等的区域Region每个区域可以是Eden区、Survivor区或Old区。这种分代的方式可以更好地适应不同对象的生命周期和内存使用模式。 2. 并发标记G1收集器使用并发标记算法在垃圾收集过程中可以与应用程序线程并发执行标记阶段减少垃圾收集对应用程序的影响。 3. 空闲区域优先回收G1收集器的名字“Garbage First”即表示它优先回收垃圾最多的区域。这种策略可以最大程度地回收垃圾提高垃圾收集的效率。 4. 可预测的停顿时间G1收集器通过将堆内存划分为多个区域并使用增量式的并发标记算法可以控制垃圾收集的停顿时间。这对于要求低延迟的应用程序非常重要。 5. 自适应调节G1收集器会根据堆内存的使用情况和垃圾收集的效果动态地调整各个阶段的参数以达到最优的垃圾收集性能。 G1收集器适用于大内存、多核处理器的应用场景尤其是需要低延迟和高吞吐量的服务端应用程序。它在处理大堆内存和大量对象时表现出色并且可以通过调整参数来满足不同应用程序的需求。