兰溪网站建设,专业制作网站公司哪家好,微舍 微网站 怎么做,海外推广渠道JVM理论
#JVM内存模型#
Java内存模型#xff08;JMM#xff09;#xff1f;
Java的内存模型决定了线程间的通信方式#xff0c;JMM的模型是由主存和工作内存构成#xff0c;两个线程想要正常通信需要将工作内存中的变量刷到主存中#xff0c;另一个线程才能正确读取得…JVM理论
#JVM内存模型#
Java内存模型JMM
Java的内存模型决定了线程间的通信方式JMM的模型是由主存和工作内存构成两个线程想要正常通信需要将工作内存中的变量刷到主存中另一个线程才能正确读取得到这个也是volitile关键词的原理所在。 JVM内存结构和Java内存模型的参考资料JVM内存结构和Java内存模型 - 知乎
JVM内存结构
JVM主要由堆JVM heap、方法区Method Area、虚拟机栈(JVM stack)、本地方法区(Native Method area)、程序计数器PCR其中堆、方法区是线程共享的和JVM的启动停止同步虚拟机栈、本地方法栈、程序计数器PCR是线程不共享的是线程私有的和线程的创建停止同步。每个结构的用途如下
堆主要存储的是对象和数组他是JVM内存模型中最大的一个区域其中又能分为年轻代和老年代年轻代又能分为Eden区和Survivor区Survivor区又能分为S0S1区这是JVM中发生GC最频繁的区域。虚拟机栈是Java方法执行的内存区域他的基本单位是栈帧每发生一次方法调用就将一个栈桢入栈方法的执行都在这个帧里面。这个帧里面包括局部数据表操作栈动态链接方法返回地址局部变量表主要存储局部变量和方法参数操作栈是方法执行的各种指令就放在操作栈里面的返回地址是记录方法调用的返回地址。本地方法区类似于虚拟机栈只是他是为了保存通过JNI方式操作本地方法的相关信息。方法区是保存类Class元信息、静态变量、常量等信息其中还包括运行时常量池其中会保存字符串常量等信息。程序计数器则保存了每个线程执行到的字节码的指令地址。 运行时内存结构
JVM的堆中包括新生代Young和老年代Old区域其中新生代包括Eden和Survivor区域其中Survivor区域包括S0和S1区域。其中新创建的对象会首先发到新生代的Eden区但是如果对象太大也会直接放到老年代其中新生代的GC是Minor GCMinor GC后存活对象会被移至Survivor区在这里会进行Major GC每一次GC都会在S0和S1中移动复制对象每次移动都会将该对象的年龄1等到满足一定的阈值就会移动到老年代中这个阈值的默认值是15。
Minor GC是在新生代发生的GC准确来说是在Eden区发生的GC。触发条件是Eden的空间不够会触发异常Minor GC。Major GC是老年代空间不够触发的GC。或者从新生代进入老年代的对象空间大于空闲空间了。Full GC是新生代和老年代共同GC。 对象内存分配的流程图 JVM堆内存分配如何保障分配对象时候的线程安全
JVM堆在创建对象时候过程
如果JIT分析判断该对象是逃逸对象就直接在栈上分配就不存在线程安全问题如果判断需要在JVM栈上分配会针对该线程在TLAB上申请一块区域该线程分配的对象登记在该区域用以解决多线程下可能发生的线程不安全问题如果该对象被判断为大对象这直接进入老年代不会在年轻代分配空间
#GC垃圾回收器#
判断对象是否可以被回收
判断对象是否可回收的方法
引用计数法每个对象有一个引用计数器每次被引用就1释放引用就-1等到为0的时候就可以被回收他的缺陷是可能存在循环引用的问题。可达性分析就是利用GC root到达对象的可达性来分析对象是否被引用如果被引用就在这条引用链中就不能回收
GC root可以由一下对象充当
虚拟机栈方法中引用的对象 类变量静态变量引用的对象 常量引用的对象 JNI引用的对象 GC Roots 是什么哪些对象可以作为 GC Root看完秒懂
GC Roots 是什么哪些对象可以作为 GC Root看完秒懂_一直Tom猫的博客-CSDN博客
GC垃圾回收算法?
GC算法分为分代算法和分区算法以下123是分区回收算法4为分代回收算法
标记-清除Mark-Sweep算法就是将失效的对象做标记等要回收的时候再清空这个对象这个算法是分代算法的基础。缺点是标记和清除的效率都不高并且可能存在较多的内存碎片。标记-整理Mark-Compact算法为了更充分的利用内存区域就是将失效的对象先标记再整理到内存区域的一侧这样整理下来的也就是一块完整的区域可以存放大对象这个是在老年代中使用的GC算法原因是老年代中对象需要回收的少触发GC的频率低。复制Copying算法为了弥补标记-清除算法可能造成内存碎片的问题就是将内存区域划分为两块每次就只用一块等到一块要满了再将有效的复制到另一块这样就能保证一块永远是空的这个在新生代中使用的GC算法原因是新生代中对象需要回收的多并且触发GC的频率高。现代的GC都分为老年代和新生代了针对各自的特征选中不同的GC算法。针对新生代他们的对象生存周期短可以选择复制这样的GC算法这样可以留出一大片空闲空间而老年代的内存中对象由于更新的慢可以选择标记-整理这样的单点清理GC算法同时也能避免内存碎片的产生。
JVM之GC算法https://www.cnblogs.com/BlueStarWei/p/9577388.html
GC垃圾回收器
GC回收器的种类1serial回收器就是在GC回收的时候停掉工作线程他是一个串行的回收器(2)parallel回收器就是GC回收器是并发执行的3CMS他的全程是concurrent mark sweep他的主要优势是在GC回收的时候不需要stop the world4G1:这个是从JDK7后推出的新的GC CMS GC垃圾回收器
CMS是并发标记清除GC回收器件其目标是获取最短GC停顿时间比较符合大型web server项目的使用场景。其GC阶段经过4个阶段
初始标记初始标记又GC root引用的对象该过程会引发STW并发标记这个是不需要STW并发标记要回收的对象重新标记这个节点重新标记并发阶段产生的新的要回收的对象并发清除并发清除标记的要回收的对象 CMS总结
优点1并发处理效率高2GC的时候不会整体停顿STW有效降低处理时延。缺点1并发清理时会降低CPU性能2标记-清理可能会造成大量内存碎片3并发清理阶段还会产生垃圾这种垃圾称为浮动垃圾需要下一次GC时才能清理掉。 G1 GC垃圾回收器
G1回收器会将区域划分为region每个region可以是新生代也可以是老年代通过控制对region的回收做到对垃圾回收导致的STW可控。垃圾回收的阶段前3个阶段和CMS一致只是最后一个节点需要通过混合清除来回收新生代和老年代所有的对象
初始标记标记GC root对象需要暂停所有用户线程该过程会引发STW并发标记标记GC root可达的对象。最终标记标记在并发标记阶段产生的需回收对象。筛选回收对各个Region的回收成本和价值进行排序根据用心要求的GC停顿时间来选择需要GC的Region。 G1总结
优点1并发处理效率高2整体停顿STW的时间可控3新生掉和老年代都分为逻辑上的region通过GC的复制算法解决内存碎片的问题缺点引入了Remembered Set来保存内存引用信息所以增加了内存占用所以G1一般在大内存的服务端环境使用起步内存大小为6G。 GC回收器总结
选择GC主要考虑的是使用场景一般嵌入式、内存较小的选择串行GC回收器对于需求吞吐量大的常见可以选择并行GC回收器对于需要时延少的场景可以选择CMS或者G1回收器
#JMV加载机制#
双亲委派模型是什么
双亲委派模型的定义
当前ClassLoader加载的class先调用双亲ClassLoader如果他们加载不了当前ClassLoader才加载所以所有的类都会被请求到Bootstrap ClassLoader简单理解就是能双亲做的事就双亲来做双亲做不了的事情就自己来做 双亲委派模型的作用
保障类的唯一性ClassLoader的双亲委派模型保障一个类在类加载器的唯一性父类已经加载了该类子类就不再加载。保障按需加载由于ClassLoader只有在需要某个类的时候才会加载某个类这样避免一次性将类全部加载进入内存引发OOM。并且当ClassLoader加载一个类时该类依赖的其他类也会由这个ClassLoader加载进来。
类加载器ClassLoader原理
ClassLoader是做什么的他是通过类的全限定名将该类的字节码转化为内存中Class对象为什么会有ClassLoader这种东西这是由于JVM对类的加载是按需延迟加载的并不是一次将所有类加载到内存空间里所以需要类加载器在内存中等待需要加载的类 ClassLoader的常用组件最顶层的Bootstrap ClassLoader主要负责加载rt.jar包里面的classExtension ClassLoader主要负责加载javax里面的java ext等类Application ClassLoader负责加载classpath里面的class文件还有Customer ClassLoader这个可以加载用户自定义的ClassLoader 老大难的 Java ClassLoader 再不理解就老了
老大难的 Java ClassLoader 再不理解就老了 - 掘金
ClassLoader进行类加载过程
类加载的过程是将类的字节码加载到内存中的过程主要包括加载--链接--初始化其中链接还包括验证、准备、解析3个步骤。
加载将class文件加载到内存在方法区生成一个java.lang.Class对象放到方法区验证验证这个class文件是否合法包括文件格式的校验元数据类型的校验等准备为类变量分配内存空间但此时只是初始化为默认值而非真实值但对于final变量此时会初始化为真实值解析将符号引用相对引用转换为直接引用符号引用是class文件的相对表达方式直接引用就是在该系统里地址指针比如hello()方法为符号引用0x12345678为直接引用初始化初始化类变量成真实值初始化静态代码段实际执行的是类构造器clinit方法。 注意类的初始化过程是懒加载的策略只有当该类被使用了才会被初始化实际就是调用clinit方法执行的过程会触发类的初始化操作条件为1需要创建新的对象执行了new操作2调用了类的静态变量或静态方法3通过反射机制来获取某个类的时候
Java 对象实例化new的过程
Java的对象实例化的过程是调用init方法在进行new操作的时候会执行实例化操作实例化的过程主要是调用构造方法的过程。在进行对象实例化之前会初始化静态变量和静态代码段然后初始化变量和代码块最后调用构造方法进行实例化。对象实例化过程 有父子关系的初始化过程先初始化父类再初始化子类。 如何判断JVM中两个类相等
同一个类的class文件被同一个classloader加载在JVM中才能判断这两个类对象相等。
Java对象Object在内存中的结构
这个是指保存在JVM堆区的的java.lang.Object对象主要包括对象头实例数据和对齐填充数据组成。
对象头包括1Mark Word这个字段包括GC标志位锁状态hashcode等数据其中锁状态包括能表征对象加锁是无锁、偏性锁、轻量级锁、重量级锁。2Klass Pointer类型指针指向方法区的类信息的指针。还有Array Length这个当对象是数组时会存在。实例数据这个保存实例变量存储对象真正的数据。对齐填充数据由于JVM规定对象数据必须为8字节的整数这个部分用来做数据填充。 Java对象在内存的结构Java对象在内存的结构 - 掘金
Java 对象结构Java 对象结构 - 掘金
JVM应用
JVM调优的主要参数和工具
JVM常用参数
-Xms设置堆的最小空间大小。-Xmx设置堆的最大空间大小。-XX:NewSize设置新生代最小空间大小。-XX:MaxNewSize设置新生代最大空间大小。-XX:PermSize设置永久代最小空间大小。-XX:MaxPermSize设置永久代最大空间大小。-Xss设置每个线程的堆栈大小。 JVM常用命令和工具
jpsjava线程查看工具jstackjava线程栈的查看工具jmapjava中堆的查看工具jstatjava内置的资源和性能监控工具jinfo实时查看和调整jvm参数
【JVM进阶之路】十JVM调优总结【JVM进阶之路】十JVM调优总结 - 知乎
GC优化的思路
GC优化的重要指标看GC频次和GC时长可以通过命令jstat查看GC优化的重要指标看CPU和内存的占用率一般在不高于70%的利用率比较合适可以调整young/old分区大小和分区比例可以调整进入永久代的年龄阈值默认是15次可以调整是否使用偏向锁
一次简单的 JVM 调优拿去写到简历里
一次简单的 JVM 调优拿去写到简历里
JVM问题排障的思路
top查询得到哪个进程id出现问题进而得到哪个线程id出问题jps查询哪个线程id出现了问题jmap查看堆内存可以dump下来jstack查看线程堆栈问题jstat进行资源监控可以查看GC数据其他
怎么制造OOM
对于堆中的OOM只需要一直创建对象对于栈中的OOM只需要一直创建线程或者进行递归调用就好对于方法区的OOM只需要一直通过反射的方法创建类就好了 注意创建之前要设置堆栈的大小
对象的强引用、软引用、弱引用、虚引用的区别
强引用只要引用存在在gc root的引用链中即可一直存在gc不掉。最常见的一种形式Object obj new Object(); 软引用gc不掉但是当oom时再次gc就会被gc掉常用来做内存敏感的缓存弱引用gc一次就会被gc掉常用来做weakHashMap来做缓存虚引用是无法使用的引用一般用来通知某对象被gc了。 引用类型强软弱虚
剖析 JDK强引用、软引用、弱引用、虚引用有何区别
剖析JDK强引用、软引用、弱引用、虚引用有何区别_28天写作_后台技术汇_InfoQ写作社区 如何对JVM进行设置让其不发生Full GC
这道题考察的关键是如果不想要发生Full GC则让对象只在新生代中进行GC尽量不要转移至老年代所以应该调整的是新生代的空间大小和比例。
Java是编译型还是解释型语言
编译型语言是通过编译器将源码编译成机器能识别的机器码在机器上能直接执行比如C/C;解释型语言是不需要进过编译直接通过解释器就能执行比如JavaScriptJava的执行过程是先通过javac编译器编译成class字节码文件再在不同平台的JVM上解释执行针对其中的热点代码还会使用JIT技术直接编译成机器码所以客观来说Java既不是编译型也不是解释型语言是结合了他们两者的混合执行方式。
JVM中JIT技术的一些常见优化策略
逃逸分析逃逸分析的基本行为是分析对象的作用于一个对象如果在方法中创建但是在方法外也会被引用这就称为该对象方法逃逸反之如果该对象只在该方法内使用则该对象未发生方法逃逸针对对象的逃逸分析后续可以进行一系列的优化策略。栈上分配一般对象存放在JVM的堆上针对未发生方法逃逸的对象即他的作用域只在该方法内所以可以在JVM栈上分配对象。
标量替换标量在程序中是指无法再分解成更小数据单元的对象比如Java中的基础数据类型就是标量而聚合量是指可以再分解成更小数据单元的对象比如Java中的类对象其至少能分解成成员变量和方法。针对未发生方法逃逸的对象则可以直接在方法内进行标量替换这样就不用分配到JVM的堆上。