当前位置: 首页 > news >正文

外贸公司网站开发百度小说风云榜

外贸公司网站开发,百度小说风云榜,做网站找个人还是找公司好,文化建设的意义什么是JVM JVM是Java设计者用于屏蔽多平台差异#xff0c;基于操作系统之上的一个小型虚拟机#xff0c;正是因为JVM的存在#xff0c;使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次#xff0c;在任何操作系统都可以以相…什么是JVM JVM是Java设计者用于屏蔽多平台差异基于操作系统之上的一个小型虚拟机正是因为JVM的存在使得Java应用程序运行时不需要关注底层操作系统的差异。使得Java程序编译只需编译一次在任何操作系统都可以以相同的方式运行。 JVM运行时区域划分 方法区 这里的方法区指的不是存放Java方法的区域它主要存放的是元数据信息例如:类信息、常量、静态变量、以及class文件在类加载时也会数据也会存放到方法区中。 堆区 堆区存储的则是对象实例数组等。例如我们日常的new 操作就是在堆区分配一个空间存放对象实例。因为堆区是线程共享区域的所以多线程情况下操作相同对象可能存在线程安全问题。 虚拟机栈和本地方法栈 虚拟机栈 我们日常对象实例的方法调用都是在虚拟机栈上运行的它是Java方法执行的内存模型存储着被执行方法的局部变量表、动态链表、方法入口、栈的操作用(入栈和出栈)。 由于虚拟机栈是栈结构所以方法调用按顺序压入栈中就会倒序弹出虚拟机栈例如我们的下面这段代码 public void a(){ b(); } public void b(){ c(); }public void c(){ }当线程调用a方法时优先为a产生一个栈帧A压入栈中发现a方法调用了b方法再为b产生一个栈帧B压入栈中然后b再调用c方法再为c产生一个栈帧C方法压入栈中。 c执行结束优先弹出栈然后是b最后是a。 由上可以在Java中方法是可以嵌套调用的但这并不意味方法可以无线层次的嵌套调用当方法嵌套调用深度超过了虚拟机栈规定的最大深度就会抛出StackOverflowError而这个错误也常常发生在我们编写的无终止条件的递归代码中。 虚拟机栈属于线程独享所以也就没有什么生命周期的概念每个方法随着调用的结束栈空间也随之释放所以栈的生命周期也可以理解为和线程生命周期是一致的。 这就使得我们虚拟机栈中的局部变量表可以被复用例如某个虚拟机栈当前局部变量表被使用的索引为0-n一旦虚拟栈执行的代码超过n位置那么n之前的内存空间就可以被再次复用。 小结一下虚拟栈的特点: 是方法执行时的内存模型。方法调用以栈帧形式压入栈中。方法嵌套调用并将栈帧压入栈帧时深度操作虚拟机栈最大深度会报StackOverflowError。虚拟机栈的局部变量表随着变量使用的完结之前的内存区域可被复用。栈的生命周期跟随线程线程调用结束栈即可被销毁。 本地方法栈 下面这个带有native关键字的方法就是在本地方法它就是本地方法栈管理的方法其工作机制和特点是虚拟机栈是差不多的所以这里就不多做介绍了。 private native void start0();程序计数器 程序计数器和我们操作系统学习的程序计数器概念差不多记录着当前线程下一条要执行的指令的地址因为是线程独享的所以程序计数器也是线程安全的。 需要注意的是程序计数器只有在记录虚拟机栈的方法时才会有值对于native方法程序计数器是不工作的。 小结 上文对运行时数据区域做了一个简单的介绍这里我们就用一张图总结一下JVM运行时区域的结构。 类加载器 什么是类加载器 类加载器实现将编译后的class文件加载到内存并转为为运行时区域划分的运行时数据结构注意类加载器只能决定类加载至于能不能运行则是由 Execution Engine 来决定。 类加载器的工作流程 类加载器工作顺序为:加载、验证、准备、解析、初始化、使用、卸载。其中验证、准备、解析这三个步骤统称为连接。 加载 将编译后class文件加载到内存。将静态数据结构转换成方法区中运行时数据结构。在堆区创建一个 java.lang.Class对象作为数据访问的入口。 连接 验证:验证这个class的类的方法是否会做出危害JVM的事情。准备:在方法区为静态变量常见空间并对其进行初始化例如private static int a3;,在此阶段就会在方法区完成创建并初始默认值0。解析:虚拟机将常量池内的符号引用转为直接引用例如import java.util.ArrayList在此阶段就会直接转为指针或者对象地址。 初始化 将方法区中准备好的值通过调用cinit完成初始化工作。cinit会收集好所有的赋值动作例如上文的private static int a3就是这时候完成赋值的。 卸载 当对象使用完成后GC将无用对象从内存中卸载。 类加载器的加载顺序 其实类加载器并非只有一个按照分类我们可以将其分为: BootStrap ClassLoaderrt.jar Extention ClassLoader: 加载扩展的jar包 App ClassLoader指定的classpath下面的jar包 Custom ClassLoader自定义的类加载器所以为了保证JDK自带rt.jar的类能够正常加载就出现了一种名为双亲委派的类加载机制。 举个例子JDK自带的包中有一个名为String的类而我们自定义的代码中也有一个String类我们自己的类肯定是由App ClassLoader完成加载如果我们的类加载器优先执行那么JDK自带的String类就无法被使用到。 所以双亲委派机制就规定了类加载优先由BootStrap ClassLoader先加载只有根加载器加载不到需要的类才会交由下层类完成加载。 正是因为双亲委派机制的存在jdk自带的String类才能够正常的使用而我们也无法通过自定义String类进行重写。 小结 类加载器的工作流程为: 加载class文件到方法区并转为运行时数据结构并在堆区创建一个Class对象作为入口验证class的类方法是否由危害JVM的行为准备阶段初始化静态变量数据解析阶段将符号引用转为可以可直接导向对象地址的直接引用初始化阶段通过cinit方法初始化对象实例变量等数据使用完成后该类就会被卸载。 用一段代码解释Java文件是如何被运行的 如下所示我们编写一个Student 类他有name这个成员属性。 /*** 学生类*/ public class Student {private String name;public String getName() {return name;}public void setName(String name) {this.name name;} } 然后我们编写一个main方法调用student类完成属性赋值。 public class Main {public static void main(String[] args) throws InterruptedException {Student student new Student();student.setName(小明);}} 首先编译得到Main.class文件后系统会启动一个JVM进程从classpath中找到这个class的二进制文件将在到方法区的运行时数据区域。 然后发现有个主入口main方法将main方法压入栈中。 main方法中需要new Student();,JVM发现方法区中没有Student类的信息于是开始加载这个类将这个类的信息存放到方法区并在堆区创建一个Class对象作为方法区信息的入口。 new Student();在此时就会根据类元信息获取创建student对象所需要的空间大小在堆区申请并开辟一个空间调用构造函数创建Student实例。 main方法调用setNamestudent 的引用找到堆区的Student通过其引用找到方法区中Student 类的方法表得到方法的字节码地址从而完成调用。 上述步骤完成后方法按照入栈顺序后进先出的弹出虚拟机栈随着线程一起销毁。 虚拟机堆 区域划分 JVM将堆内存分为年轻代和老年代。以及非堆内存区域我们称为永久代这里所说的永久代只有在Java8之前才会出现。在Java8之后因为兼容性原因永久代的东西都被放置到元空间元空间所使用的内存都是本地内存,这里的本地内存说的就是我们物理机上的内存所以理论上物理机内存多大元空间内存就可以分配多大元空间大小分配和JVM从物理机上分配的内存大小没有任何关系。 补充元空间两个参数 MetaspaceSize初始化元空间大小控制发生GCMaxMetaspaceSize限制元空间大小上限防止占用过多物理内存。年轻代 了解整体空间之后我们再来聊聊年轻代年轻又可以分为Eden和Survivor区Survivor区又被平均分为两块。所以年代整体比例为8:1:1。当然这个值也可以通过-XX:UsePSAdaptiveSurvivorSizePolicy来调整。 任何对象刚刚创建的时候都会放在Eden区。我们都知道堆区内存是共享的所以Eden区的空间也是多线程共享的但是为了确保多线程彼此之间相对独立(注意是线程之间彼此独立而不是操作Eden区对象独立)Eden区会专门划出一块连续的空间给每个线程分配一个独立空间这个空间叫做TLAB空间。每个线程都可以操作自己的TLAB空间和读取其他线程的TLAB空间。 一旦Eden区满了之后就会触发第一次Minor GC就会将存活的对象从Eden区放到Survivor区。 Survivor区就比较特别了它分为Survivor0和Survivor1区。JVM使用from和to两个指针管理这两块区域其中from指针指向有对象的区域空间to指针指向空闲区域的Survivor空间。 从Eden区中存活下来首先会在Survivor0区(此时from指针在Survivor0)一旦下一次Eden区空间满了之后就再次触发 Minor GC 将Eden区和Survivor0区存活的对象复制到Survivor1区然后from指针指向Survivor1结束一次minor GC。 经过15次之后还活着的对象就会被存放到老年代这里是15是由-XX:MaxTenuringThreshold指定的 -XX:MaxTenuringThreshold 占4位,默认配置为15。 这里补充一下同样会将Survivor存放到老年代的第2个条件当Survivor区对象比例达到XX:TargetSurvivorRatio时也会将存活的对象放到老年区。 老年代 老年代存放的都是经历过无数次GC的老对象一旦这个空间满了之后就会出现一次Full GCFull GC期间所有线程都会停止手头工作等待Full GC完成所以在此期间系统可能会出现卡顿现象。 这就意味着在高并发多对象创建场景的情况下我们需要合理分配老年区的内存。一旦Full GC后还是无法容纳新对象就会报OOM问题。 JVM如何判断对象是否需要被销毁 引用计数器法 这种了解就好了一个对象被引用时1被解除引用时-1。我们根据引用计数结果决定是否GC但是这种方式无法解决两个对象互相引用的情况。例如我们栈区没有一个引用指向当前两个对象可堆区两个对象却互相引用对方。 可达性分析法 将一系列的GC ROOTS作为起始的存活对象集查看是否有任意一个GC ROOTS可以到达这个对象都不可达就说明这个对象要被回收了。 而以下几种可以作为GC ROOTS: 虚拟机栈中的局部变量等,被该变量引用的对象不可回收。方法区的静态变量被该变量引用的对象不可回收。方法区的常量,被该变量引用的对象不可回收。本地方法栈即native修饰的方法,被该变量引用的对象不可回收。未停止且正在使用该对象的线程,被该线程引用的对象不可回收。 判断对象是否需要真正回收 判断对象是否被回收需要经过两个阶段: 经过上文介绍的可达性分析法发现不可达的对象后就将其第一次标记一下然后判断该对象的是否要执行finalize()方法若确定则将其存到F-Queue中。将F-Queue中的对象调用finalize()若此时还是没有任何引用链引用则说明这个对象要被回收了。 垃圾回收算法(重点) 标记清除法 如下图这种算法很简单标记出需要被回收的对象的空间然后直接清除。同样的缺点也很明显容易造成内存碎片内存碎片也很好理解回收的对象空间都是一小块一小块的当我们需要创建一个大对象时就没有一块连续大空间供其使用。 复制算法 这种算法和上文说的survivor一样将空间一分为二from存放当前活着的对象to作为空闲空间。在进行回收时将没有被标记回收的对象挪到另一个空间然后from指向另一个空间。这种算法缺点也很明显可利用空间就一半。 标记整理 这种算法算是复制算法的改良版将存活对象全部挪动到一段确保空闲和对象空间都是连续的且空间利用率100%。 分代收集算法(综合算法) 这种算法就是上面算法的组合即年轻代存活率低采用复制算法。老年代存活率高采用标记清除算法或者标记整理算法。 JVM常见工具介绍 jinfo(查看配置信息) 查看Java应用程序配置参数或者JVM系统属性相关命令详情我们可以使用-help或者man命令查看如下所示: [rootxxxxxtmp]# jinfo -help Usage:jinfo [option] pid(to connect to running process)jinfo [option] executable core(to connect to a core file)jinfo [option] [server_id]remote server IP or hostname(to connect to remote debug server)where option is one of:-flag name to print the value of the named VM flag-flag [|-]name to enable or disable the named VM flag-flag namevalue to set the named VM flag to the given value-flags to print VM flags-sysprops to print Java system propertiesno option to print both of the above-h | -help to print this help message为了演示笔者在服务器上开启了一个Java应用我们可以使用jps命令查看其进程id,可以看到笔者服务器中有一个pid为19946的Java进程。 [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]# jps 20104 Jps 19946 jar 查看当前应用所有的配置参数以及系统配置属性命令为jinfo pid如下所示: [rootxxxxx tmp]# jinfo 19946 Attaching to process ID 19946, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.202-b08 Java System Properties:java.runtime.name Java(TM) SE Runtime Environment java.vm.version 25.202-b08 sun.boot.library.path /root/jdk8/jre/lib/amd64 java.protocol.handler.pkgs org.springframework.boot.loader java.vendor.url http://java.oracle.com/ java.vm.vendor Oracle Corporation path.separator : file.encoding.pkg sun.io java.vm.name Java HotSpot(TM) 64-Bit Server VM sun.os.patch.level unknown sun.java.launcher SUN_STANDARD user.country US user.dir /tmp...... 如果我们希望查看当前Java应用是否有配置某些信息可以使用命令jinfo -flag 配置选项 pid例如我们想查看当前应用是否有开启gc选项可以使用下面这段命令 可以看到输出结果为-XX:-PrintGC因为PrintGC前面是减号这说明该选项并没有开启。 [rootxxx tmp]# jinfo -flag PrintGC 19946 -XX:-PrintGC 如果我们希望将这个选项开启我们只需在参数前面加个号即可例如我们希望开启gc选项我们只需键入如下命令 [rootxxxxxtmp]# jinfo -flag PrintGC 19946 再次查看可以发现选项生效了 [rootxxxx tmp]# jinfo -flag PrintGC 19946 -XX:PrintGC有些参数是键值对的形式例如我们想配置dump日志的路径我们也可以使用jinfo进行配置命令格式为jinfo -flag 参数值 Java进程id jinfo -flag HeapDumpPath/tmp/dump.log 19946打印JVM选项信息 jinfo -flags 4854 Attaching to process ID 4854, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.202-b08 Non-default VM flags: -XX:CICompilerCount2 -XX:HeapDumpPathnull -XX:InitialHeapSize33554432 -XX:MaxHeapSize511705088 -XX:MaxNewSize170524672 -XX:MinHeapDeltaBytes196608 -XX:NewSize11141120 -XX:OldSize22413312 -XX:PrintGC -XX:UseCompressedClassPointers -XX:UseCompressedOops -XX:UseFastUnorderedTimeStamps Command line:查看应用属性命令格式jinfo -sysprops Java进程id jinfo -sysprops 2341jmap(查看堆区信息、对象信息等) jmap作用: 查看使用的GC算法堆的配置信息以及各个内存区域的内存使用情况显示堆对象的统计信息包括每一个Java类、对象数量、内存大小、类名称等打印等会回收的对象的信息生成dump文件配合jhat使用 查看堆内存使用情况 jmap -heap Java进程id [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]# jmap -heap 25534 Attaching to process ID 25534, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.202-b08using thread-local object allocation. Mark Sweep Compact GCHeap Configuration:MinHeapFreeRatio 40MaxHeapFreeRatio 70MaxHeapSize 511705088 (488.0MB)NewSize 11141120 (10.625MB)MaxNewSize 170524672 (162.625MB)OldSize 22413312 (21.375MB)NewRatio 2SurvivorRatio 8MetaspaceSize 21807104 (20.796875MB)CompressedClassSpaceSize 1073741824 (1024.0MB)MaxMetaspaceSize 17592186044415 MBG1HeapRegionSize 0 (0.0MB)查看存活的Java对象(文档说明:to print histogram of java object heap; if the “live” suboption is specified, only count live objects)命令格式: jmap -histo:live Java进程id [rootxxxtmp]# jmap -histo:live 25534num #instances #bytes class name ----------------------------------------------1: 48676 7974952 [C2: 7762 1873312 [I3: 47785 1146840 java.lang.String4: 12737 1120856 java.lang.reflect.Method5: 8773 968912 java.lang.Class6: 25572 818304 java.util.concurrent.ConcurrentHashMap$Node7: 14108 564320 java.util.LinkedHashMap$Entry8: 2712 509536 [B9: 9308 494936 [Ljava.lang.Object;10: 6345 493128 [Ljava.util.HashMap$Node;11: 7001 392056 java.util.LinkedHashMap12: 11255 360160 java.util.HashMap$Node13: 15946 354528 [Ljava.lang.Class;14: 18176 290816 java.lang.Object15: 3447 248184 java.lang.reflect.Field16: 124 192320 [Ljava.util.concurrent.ConcurrentHashMap$Node;打印正在被回收的类**(文档说明:to print information on objects awaiting finalization)**,命令格式:jmap -finalizerinfo Java进程id [rootxxxtmp]# jmap -finalizerinfo 25534 Attaching to process ID 25534, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.202-b08 Number of objects pending for finalization: 0将存活的对象的信息存到二进制文件中 jmap -dump:live,formatb,file/tmp/heap.bin 25534 Dumping heap to /tmp/heap.bin ... Heap dump file created此时就可以使用jhat打开该文件,如下所示jhat 文件名,这时候我们就可以通过7000端口查看详情了。 [rootxxxtmp]# jhat heap.bin Reading from heap.bin... Dump file created Wed Nov 02 20:21:18 CST 2022 Snapshot read, resolving... Resolving 346825 objects... Chasing references, expect 69 dots..................................................................... Eliminating duplicate references..................................................................... Snapshot resolved. Started HTTP server on port 7000 Server is ready.jstat(常用监控运行时状态信息) jstat用于监控虚拟机各种运行状态信息显示虚拟机进程中装在、内存、垃圾收集、JIT编译等运行数据。 查看类加载信息命令格式jstat -class Java进程id [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]# jstat -class 2341 Loaded Bytes Unloaded Bytes Time8221 14604.3 1 0.9 12.74 [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]#查看编译统计信息jstat -compiler Java进程id [rootxxxtmp]# jstat -compiler 2341 Compiled Failed Invalid Time FailedType FailedMethod4177 0 0 17.68 0 [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]#查看gc统计信息 [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]# jstat -gc 2341S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 1408.0 1408.0 0.0 1020.3 11840.0 7493.1 29268.0 22168.5 42840.0 40613.5 5760.0 5311.9 65 0.401 2 0.213 0.613 [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]#每个表头的含义如下 1. S0C :年轻代中第一个survivor幸存区的容量 (字节) 2. S1C :年轻代中第二个survivor幸存区的容量 (字节) 3. S0U:年轻代中第一个survivor幸存区目前已使用空间 (字节) 4. S1U:年轻代中第二个survivor幸存区目前已使用空间 (字节) 5. EC:年轻代中Eden伊甸园的容量 (字节) 6. EU:年轻代中Eden伊甸园目前已使用空间 (字节) 7. OC:Old代的容量 (字节) 8. OU:Old代目前已使用空间 (字节) 9. PC:Perm(持久代)的容量 (字节) 10. PU:Perm(持久代)目前已使用空间 (字节) 11. YGC:从应用程序启动到采样时年轻代中gc次数 12. YGCT:从应用程序启动到采样时年轻代中gc所用时间(s) 13. FGC:从应用程序启动到采样时old代(全gc)gc次数 14. FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s) 15. GCT:从应用程序启动到采样时gc用的总时间(s) 查看gc内存容量和元空间容量 [rootxxxtmp]# jstat -gccapacity 2341NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC10880.0 166528.0 14656.0 1408.0 1408.0 11840.0 21888.0 333184.0 29268.0 29268.0 0.0 1087488.0 42840.0 0.0 1048576.0 5760.0 65 2查看年轻代统计信息 [rootxxxxtmp]# jstat -gcnew 2341S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT 1408.0 1408.0 0.0 1020.3 2 15 704.0 11840.0 7652.5 65 0.401 [rootiZ8vb7bhe4b8nhhhpavhwpZ tmp]#参数详情 1. S0C:年轻代中第一个survivor幸存区的容量 (字节) 2. S1C:年轻代中第二个survivor幸存区的容量 (字节) 3. S0U:年轻代中第一个survivor幸存区目前已使用空间 (字节) 4. S1U:年轻代中第二个survivor幸存区目前已使用空间 (字节) 5. TT:持有次数限制 6. MTT:最大持有次数限制 7. EC:年轻代中Eden伊甸园的容量 (字节) 8. EU:年轻代中Eden伊甸园目前已使用空间 (字节) 9. YGC:从应用程序启动到采样时年轻代中gc次数 10. YGCT:从应用程序启动到采样时年轻代中gc所用时间(s)补充 Minor GC、Major GC 和 Full GC 之间的区别 Minor GCMajorGC、Full GC minor gc 会发生stop the world 现象吗 - 红色的红的回答 - 知乎 https://www.zhihu.com/question/29114369/answer/2287094858 参考文献 大白话带你认识JVM Java 性能调优实战 MaxTenuringThreshold 和 TargetSurvivorRatio参数说明 Java 堆内存是线程共享的面试官你确定吗 Java8中的JVM元空间是不是方法区 JVM中新生代为什么要有两个Survivor jstat命令详解 JVM基础三一个对象的创建过程
http://www.dnsts.com.cn/news/37224.html

相关文章:

  • 基于asp.net网站开发wordpress访问加速
  • 找平面设计师网站柳州最新消息
  • 做网站在什么是网络营销4p策略
  • 免费下载网站软件中国flash网站模板中心
  • 深圳网站设计公司费用大概多少单位门户网站怎么做
  • 徐州网站排名系统仙居做网站公司
  • 长葛网站建设公司上海网站建设在哪
  • 网站由哪三部分组成网络运营和网站运营
  • 自己怎么做视频网站wordpress 多重排序
  • 上海技术公司做网站百度一下京东
  • 写网站的教程包含导航栏至少包含三个布局
  • 微信分身网页版网址网站 seo
  • 做静态网站的软件唐山地区网站开发公司
  • 网站权重等级wordpress插件导出
  • 徐州新站百度快照优化网站 版本 白名单 wap 解析
  • 怎样使用wordpress无锡做网站优化
  • WordPress蜘蛛爬行插件泉州seo关键词排名
  • 怎么提高网站打开速度公司起名大全免费版
  • 学校网站建设费用wordpress文章一部分加密
  • 做网站如何选择颜色电子商务网站建设与管理的背景
  • 做网站设计需要学会哪些信阳做网站的
  • 建设营销网站的四个步骤找兼职h5网站开发人员
  • 蓟县网站建设流媒体视频网站建设
  • 专门做拼花网站php如何自学做网站
  • 搭建cms网站做网站制作怎么样
  • 企业网站优化要多少钱synology建设网站
  • 企业怎么建网站临泉网站建设
  • 网站建设确认报告建一个类似京东的网站
  • 网站的控制面板门户网站的营销方式
  • 用rp怎样做网站成都网站商城建设