JAVA中JVM运行时数据区的示例分析

发布时间:2021-09-02 13:46:18 作者:小新
来源:亿速云 阅读:177

这篇文章主要为大家展示了“JAVA中JVM运行时数据区的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JAVA中JVM运行时数据区的示例分析”这篇文章吧。

一、前言

将对整个JVM运行时数据区和GC垃圾回收详细的介绍

二、运行时数据区整体概架构

JAVA中JVM运行时数据区的示例分析

以下是自己的一句话总结:

分为线程私有和线程共享的两大类,其中程序计数器、虚拟机栈、本地方法栈是属于线程私有的,堆内存及方法区内存是线程共享的。程序计数器主要是记录字节码指令,CPU上下文切换线程,从一个线程切换到另一个线程,需要知道线程执行到哪一步,所以记录这个指令就是很有必要的,程序计数器无OOM和GC的发生。虚拟机栈里面是一个个栈帧,每一个栈帧对应着每一个方法,栈帧又是由局部变量表、操作数栈、方法返回值地址、动态链接组成。虚拟机栈可能会发生栈溢出异常,即starkoverflow本地方法栈是存放本地方法相关的东西;堆是一块很大的空间,整体分为2大块,新生代和老年代,新生代又分了Eden区、S0区、S1区,垃圾回收主要发生在新生代,每一个区对应不同的垃圾回收算法;方法区保存的是一些常量、类的基本信息等,方法区对应的实现在JDK7中是永久代,在JDK8中是元空间。

三、程序计数器

用来储存指向下一条指令的地址,是线程私有的,生命周期和线程的生命周期一致。

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

四、虚拟机栈

虚拟机栈是线程私有的,内部保存一个个栈帧,每一个栈帧对应一个Java方法的调用,生命周期和线程的生命周期保持一致。先来看看栈的特点。

JAVA中JVM运行时数据区的示例分析

1、栈的特点

栈是运行时的单位,而堆是存储的单位。栈的特点是先进后出,后进先出。

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

可以通过参数-Xss来设置栈空间大小

2、栈帧的内部结构

JAVA中JVM运行时数据区的示例分析

3、局部变量表

是一个数字数组,主要用于存储方法参数和定义在方法内的局部变量,这些数据类型包括各类基本数据类型,对象引用等,所需的容量大小是在编译期确定下来的,在方法运行期间是不会改变局部变量表大小的。

关于Slot的理解:

JAVA中JVM运行时数据区的示例分析

静态变量和局部变量的区别:

JAVA中JVM运行时数据区的示例分析

总结:

在栈帧中,与性能关系最为密切的就是局部变量表,在方法执行时,虚拟机使用局部变量表完成完成方法的传递,局部变量表中的数据也是可达性分析中的GC Root,如果一个对象在局部变量表中还有引用,那么根绝可达性分析算法,这个变量就不属于垃圾对象,是不会被GC回收的。

4、操作数栈

操作数栈是栈中栈,也可称为表达式栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈和出栈。主要用于保存计算过程的中间结果。操作数栈,可以看成是临时寄存器,计算过程中变量的临时保存

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

5、动态链接

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

方法重写的本质

JAVA中JVM运行时数据区的示例分析

6、方法返回地址

存放调用该方法的PC寄存器的值

JAVA中JVM运行时数据区的示例分析

五、本地方法栈

管理本地native本地方法,是线程私有的,所谓的本地方法,其实就是一些非Java语言写的代码,这部分代码甚至可以和操作系统CPU进行打交道。

六、堆

堆是内存管理的核心区域,是线程共享的,属于JVM级别,也就是一个JVM实例就会有一个堆空间,注意的是虽然堆整体上是线程共享的,但是在内部有一小块空间是线程私有的缓存区TLAB。

几乎所有的对象实例都是在堆中,堆是GC垃圾回收的重点区域。堆整体可以分为新生代和老年代,新生代又分为Eden区和S0和S1区。

JAVA中JVM运行时数据区的示例分析

新生代和老年代的比例是1:2,Eden区和s0,s1区所占空间比例是8:1:1

1、设置堆大小的参数

-Xms:用于表示堆区的起始内存,默认情况下,占物理内存大小的64分之一。

-Xmx用于表示堆区的最大内存,默认情况下,占物理内存的四分之一。

通常起始内存和最大内存两个参数设置成一样,目的是为了GC清理完堆区内存后不需要重新分隔
计算堆区的大小,从而提高性能。
查看设置的参数:
方式一:jps(查看进程)  
            jstat -gc 进程id
方式二:-xx:+printGCDetails

2、对象分配过程

JAVA中JVM运行时数据区的示例分析

这里s0和s1谁是空的谁就是to,年龄计数器阈值是15,YGC是在Eden区满的时候会触发,s0和s1满的时候不会触发YGC,YGC会将s区以及伊甸园区一起GC

关于垃圾回收,频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间收集。

JAVA中JVM运行时数据区的示例分析

Visualvm是JVM常用调优工具,在JDK的bin下就可以打开

3、堆中的GC

JAVA中JVM运行时数据区的示例分析

年轻代(Minor GC)触发机制

JAVA中JVM运行时数据区的示例分析

老年代GC(Major GC/Full GC)触发机制

Full GC 触发机制

JAVA中JVM运行时数据区的示例分析

4、内存分配策略

JAVA中JVM运行时数据区的示例分析

5、什么是TLAB

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

TLAB表明堆不一定是共享的。

6、堆是分配对象存储的唯一选择吗?

如果经过逃逸分析,一个对象并没有逃逸出方法的话,那么就有可能被优化成栈上分配。

逃逸分析手段:

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

注意:JDK6U23版本后,HotSpot默认已经开启逃逸分析。所以我们得出一个结论,开发中能使用局部变量的,就不要使用在方法外定义。JDK7后字符串常量池和静态变量存储在堆中

七、方法区

方法区可以看做是一块独立于堆的内存空间,是线程共享的,主要存储类信息、运行时常量池等,也会发生OOM,JDK8前成为永久代,JDK8成为元空间。(元空间和永久代最大的区别是,元空间不再使用JVM内存,而是使用了本地内存技术)

1、方法区概述

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

2、设置方法区内存大小

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

3、如何解决OOM问题?

JAVA中JVM运行时数据区的示例分析

4、方法区存储什么

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

5、方法区的演进细节

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

6、方法区的GC

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

JAVA中JVM运行时数据区的示例分析

以上是“JAVA中JVM运行时数据区的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

推荐阅读:
  1. JVM运行时的数据区域介绍
  2. JVM运行时数据区如何划分

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java jvm

上一篇:Go如何操作etcd

下一篇:kotlin之闭包的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》