关于java:JVM整理二

5次阅读

共计 1707 个字符,预计需要花费 5 分钟才能阅读完成。

JVM 介绍

运行时数据区

运行时数据区能够分为: 办法区、堆、虚拟机栈、本地办法栈、程序计数器. 其中办法区和堆为线程共享区, 虚拟机栈、本地办法栈和程序计数器为线程独享区. 线程独享区的内存空间随线程的创立被开拓, 随线程的销毁被回收, 所以垃圾回收器次要是作用在办法区和堆区.

堆能够被分为新生代和老年代, 其中新生代由能够分为 eden 区和 surrivor1、surrrivor2 区. 老年代和新生代默认占比为 2:1, 能够通过 -XX:NewRatio= 2 配置从新设置占比.Eden 和 S1、S2 的占比为 8:1:1, 能够通过 -XX:NewSurrivor= 4 配置从新设置占比.

堆大小设置

-Xms:256M 设置 JVM 的初始内存大小, 默认是为零碎内存的 1 /64 之一;
-Xmx:256M 设置 JVM 的最大内存大小, 默认是为零碎内存的 1 / 4 之一;
通常咱们优化是将初始化内存和最大内存设置为一样的值, 这样能够防止不必要的 major gc 或 full gc, 造成 STW, 引起程序利用不必要的卡顿.

回收算法

新生代个别都会采纳复制算法, 该算法的效率较高且满足新生代的对象个性. 当新生代数据区满时, 个别状况下新生代百分之八十左右的数据都可能被回收掉, 留下的数据和 S1 区域会被回收的数据一起复制到 S2 区. 第二次放生 minor gc 时,eden 和 S2 存活的对象会被复制到 S1 区, 默认状况下, 存活的对象默认状况下达到 15 时, 下次产生 minor gc 时, 该存活的对象会放到老年代中. 能够通过 -XX:MaxTenuringThreshold=15 配置从新设置新生代对象的最大年龄.
老年代会采纳标记革除或标记整顿算法. 标记革除会产生内存空间碎片, 须要额定保护一个闲暇列表, 但相较于标记整顿算法会快一些. 标记整顿是先将标记存活的对象都压缩到内存的一端, 最初在清理掉边界之外的所有空间, 所以不会产生内存碎片.

办法区

办法区是 JVM 标准, 不同 jdk 版本之间的实现各有不同.jdk1.7 及以前, 办法区的实现是永恒代 (Permanent Generation), 能够通过 -XX:Permsize 和 -XX:MaxPermsize 来调配永恒代的初始空间和最大可调配空间.JDK8 采纳元空间来替换永恒代, 最大的区别是元空间不在 JVM 设置的内存中, 而是应用本地内存, 能够通过 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 指定元空间的初始和最大空间.
办法区内寄存的构造为类信息和运行时常量池, 字符串常量池、动态变量在 1.7 及当前被划分到了堆中. 该区也会产生垃圾回收解决.

虚拟机栈默认大小为 1M, 当遇到递归次数较多的办法, 可能会产生 StackOverFlowError 异样, 能够通过 -Xss100m 指令配置调整栈内存大小.
每个线程都会对应一个虚拟机栈, 多个线程就会对应多个虚拟机栈. 一个虚拟机栈外面会蕴含多个栈帧, 每一个栈帧是为办法执行而创立的, 栈帧中形容的是 java 办法执行的内存模型.
栈帧中蕴含局部变量表、操作数栈、动静链接、返回地址.

局部变量表

它定义为数字数组, 次要用于存储办法参数和定义在办法内的局部变量. 局部变量表所需的容量在编译期间确定,在运行期间是不扭转其容量.

操作数栈

它是一个后进先出的栈, 依据字节码指令, 往栈中写入或取出数据. 操作包含: 复制、替换、求和等.

动静链接

被调用的办法在编译期间无奈被确定下来, 只能在程序运行时将调用办法的符号援用转换为间接援用,因为这种援用转换的过程具备动态性, 被称为动静链接.

办法返回地址

办法在返回的时候须要在栈帧中保留一些信息, 用来复原调用该办法的下层办法的执行状态.

程序计数器

程序计数器就是一块较小的内存空间, 它是以后线程执行字节码的行号指示器. 每个栈帧都会保护一个属于本人的程序计数器, 这个计数器就是用来记录执行的地址的.

本地办法栈

本地办法栈和虚拟机栈类所施展的作用十分相似. 它们之间的区别就是虚拟机栈为虚拟机执行 Java 办法服务, 而本地办法栈为虚拟机所应用到的 native 办法服务. 本地办法只有被调用之前,DLL 才会被加载, 即通过调用 java.system.loadLibrary()实现的.

[下一章节 介绍执行引擎]

正文完
 0