《性能调优之JVM》??02JVM内存模型深度剖析与优化
??作者主页:
温文尔雅的清欢渡
?? 近期学习方向:
性能调优
??欢迎 点赞 👍 收藏 ? 留言 📝 关注 ? 私聊我
前言
一、JDK体系结构与跨平台特性
JDK体系结构
- JDK: JDK提供了编译、运行Java程序所需的各种资源和工具;包括Java编译器,Java运行时环境【JRE】;开发工具包括编译工具(javac.exe) 打包工具(jar.exe)等;
- JRE: 即JAVA运行时环境,JVM就是包括在JRE中,以及常用的JAVA类库等;
- JVM: Java虚拟机,负责运行java程序的机器;
- SDK: SDK是基于JDK进行扩展的,是解决企业级开发的工具包。如JSP、JDBC、EJB等就是由SDK提供的 ;
跨平台特性:java语言编写的程序,一次编译后,可以在多个系统平台上运行。 实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。
二、JVM内存模型深度剖析
JVM中由内存模型、类装载子系统、字节码执行引擎组成。
JVM内存模型有本地方法栈、虚拟机栈、程序计数器、堆、方法区。 JVM内存分为共享区(可以被所有线程直接访问)和私有区(对线程来说是私有的,其他线程无法直接访问)。 在共享区里包含着堆和方法区,在私有区里包含着程序计数器、虚拟机栈和本地方法栈。 程序计数器PC:是一个行号计数器,程序在进行跳转时,我们要记住跳转的行号,它方便我们的程序进行还原。 虚拟机栈:包含了Java方法执行时的状态,每一个Java方法都会在虚拟机栈里面创建一个栈帧,里面存放局部变量表、操作数栈、动态链接、方法出口等。 本地方法栈:跟虚拟机栈类型,在用于调用操作系统的底层方法时才会创建栈帧。 堆:用来保存着Java程序运行时的变量,比如new的对象。 方法区:则保存着静态的东西,比如静态变量、常量、类的信息、方法的申明等。
局部变量表:存放局部变量的空间,存放对象在堆中的内存地址。 操作数栈:程序在运行过程中,进行运算操作的临时存储空间。 动态链接:存放着方法在方法区的入口地址。 方法出口:记录着方法执行的线程位置,为了执行完方法后可以回到原来的位置 ,还存着返回值。
三、JVM内存参数设置
Spring Boot程序的JVM参数设置格式(Tomcat启动直接加在bin目录下catalina.sh文件里): java ‐Xms2048M ‐Xmx2048M ‐Xmn1024M ‐Xss512K ‐XX:MetaspaceSize=256M ‐XX:MaxMetaspaceSize=256M ‐jar microservice‐eurek a‐server.jar 关于元空间的JVM参数有两个:-XX:MetaspaceSize和 -XX:MaxMetaspaceSize -XX:MaxMetaspaceSize: 设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小。 -XX:MetaspaceSize: 指定元空间触发Fullgc的初始阈值, 以字节为单位,默认是21M,达到该值就会触发 full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超过-XX:MaxMetaspaceSize 一般建议将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大, 对于8G物理内存的机器来说,一般将这两个值都设置为256M。 ‐Xss128k(默认1M) -Xss设置越小count值越小,说明一个线程栈里能分配的栈帧就越少,但是对JVM整体来说能开启的线程数会更多。
四、Gc Root
Gc Root是根对象,从这些节点开始向下搜索引用的对象,找到的对象被标记为非垃圾对象,其余未标记的对象都是垃圾对象。 Gc Root根节点:栈中的本地变量、?法区中的静态变量、本地?法栈中的变量、正在运行的线程等。
五、STW机制
STW:stop the word ,当JAVA进行Gc时,会停止用户线程,对用户体验很不好。 full gc比minor gc的时间要长。
六、JVM为什么要使用STW?
反证法,Gc要进行垃圾回收,先找Gc Root,然后找非垃圾对象。 如果没有STW,用户线程将一直执行。Gc在线程执行的过程中找了非垃圾对象,然后线程结束,内存空间都被释放了,栈帧弹出,Gc Root已经没了,之前找的非垃圾已经全变成垃圾了。
|