性能测试之 JVM 概念认识
无论什么语言,在程序运行过程中,都需要对内存进行管理,要知道计算机/服务器的内存不是无限的。例如:C语言中需要对对象的内存负责,需要用delete/free来释放对象;那JAVA中,对象的内存管理是由JVM自动管理的。
JVM是很有必要的了解认识的,因为在程序性能调优中极其重要的两个判断方向——运行时间和运行空间,都需要具备JVM的知识理解和工具使用,知其所以然才能无往不利
JVM虚机机的历史和类型
内存模型
程序计数器
- 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在Java虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成
- 线程私有内存
- 唯一一个不会发生任何OutOfMemoryError的区域
Java虚拟机栈
- 每个方法被执行的时候,Java虛 拟机都会同步创建-一个栈帧 ( Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
局部变量表存放了编译期可知的各种Java虚拟机基本数据类型( boolean、byte、 char、 short、 int、float、long、 double) 、对象引用和returnAddress类型 - 线程私有内存
- 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果Java虛拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemory Error异常
本地方法栈
- 与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。
- 栈深度溢出或者栈扩展失败时分别抛出StackOverflowError和OutOfMemoryError异常
Java堆
- 几乎所有的对象实例以及数组都应在堆上分配。
如上图的一个区域划分,是比较主流的经典的设计。不是绝对的划分标准,是存在一些VM/垃圾回收器与如上标准不同 - 线程共享内存
- 如果在Java堆中没有内存完成实例分配,并且堆也无法再扩展时,Java虛拟机将会拋出OutOfMemoryError异常
方法区
- 用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。有一个别名叫作“非堆”(Non-Heap),目的是与Java堆区分
- 线程共享内存
- 如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。
运行时产量池
- 运行时常量池是方法区的一部分。Class文 件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池表,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
- 线程共享内存
- 既然运行时常量池是方法区的一部分,自然受到方法区内存的限制,当常量池无法再申请到内存时会拋出OutOfMemoryError异常
直接内存
- 在JDK 1.4中新加入了NIO类,引入了一种基于通道(Channel) 与缓冲区( Buffer)的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在Java堆和Native堆中来回复制数据
- 直接内存的分配不会受到Java堆大小的限制,但是受到本机总内存的限制。
配置虚拟机参数时,会根据实际内存去设置VM的参数信息,但经常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常
扫一扫,关注我
性能测试之 JVM 概念认识的更多相关文章
- 性能测试之JVM的故障分析工具VisualVM
VisualVM 是随JDK一同发布的jvm诊断工具,通过插件可以扩展很多功能,插件扩展也是其精华所在. 提供了一个可视界面,用于在Java应用程序在Java虚拟机上运行时查看有关Java应用程序的详 ...
- 性能测试之JVM的故障排查-堆内存泄漏
JVM异常说明(超链接) 一文中已介绍了,JVM每个运行时区域--程序计数器 .Java虚拟机栈.本地方法栈.Java堆.方法区.直接内存发生OutOfMemoryError的不同原因和不同错误信息. ...
- 性能测试之JVM的故障排查-死锁
死锁原因 Java发生死锁的根本原因是:在申请锁时发生了交叉闭环申请.即线程在获得了锁A并且没有释放的情况下去申请锁B,这时,另一个线程已经获得了锁B,在释放锁B之前又要先获得锁A,因此闭环发生,陷入 ...
- 性能测试之JVM的监控Grafana
安装配置Grafana参考 https://testerhome.com/articles/23629 使用配置 下载jmx_exporter https://github.com/prometheu ...
- 公司HBase基准性能测试之结果篇
上一篇文章<公司HBase基准性能测试之准备篇>中详细介绍了本次性能测试的基本准备情况,包括测试集群架构.单台机器软硬件配置.测试工具以及测试方法等,在此基础上本篇文章主要介绍HBase在 ...
- 性能测试之JMeter远程模式
性能测试之JMeter远程模式 事实上,你的JMeter客户端机器是不能表现出完美的压力请求,来模拟足够多的用户或由于网络限制去向服务施加压力,一种解决方法是通过一个JMeter去控制多个/远程JMe ...
- 性能测试之Windows常见性能计数器
性能计数器(counter)是描述服务器或操作系统性能的一些数据指标.计数器在性能测试中发挥着“监控和分析”的关键作用,尤其是在分析系统的可扩展性.进行性能瓶颈的定位时,对计数器的取值的分析非常关键. ...
- 性能测试培训:Ajax接口级性能测试之jmeter版
性能测试培训:Ajax接口级性能测试之jmeter版 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest认为工具 ...
- 老李分享知识:性能测试之TPS和吞吐率
老李分享知识:性能测试之TPS和吞吐率 当增大系统的压力(或添加并发用户数)时,吞吐率和TPS的改变曲线呈大体一致,则系统基本稳定. 若压力增大时,吞吐率的曲线添加到一定程度后出现改变缓 ...
随机推荐
- 用项目强化你的webpack
用你的webpack实现vue-cli 本文围绕前端工程化,用webpack从零搭建一个完整项目的过程 本文核心知识点: webpack的使用 vue组件化思想 Element-UI的使用 别走别走, ...
- linux常用命令---PATH与防火墙
linux的路径PATH 防火墙
- HTML5 Canvas绘图如何使用
--------------复制而来--原地址http://jingyan.baidu.com/article/ed15cb1b2e642a1be369813e.html HTML5 Canvas绘图 ...
- 设置TextField的响应View和toolBar
inputView 设置用于展示的响应View 类似于键盘的展示方式 inputAccessoryView 用于设置响应View上面的ToolBar 使用方式: inputView设置为响应View ...
- 两圆相交求面积 hdu5120
转载 两圆相交分如下集中情况:相离.相切.相交.包含. 设两圆圆心分别是O1和O2,半径分别是r1和r2,设d为两圆心距离.又因为两圆有大有小,我们设较小的圆是O1. 相离相切的面积为零,代码如下: ...
- 【Java_Eclipse】Eclipse插件如何卸载?
本博客我们讲一下对于Eclipse的插件卸载 1.Eclipse中:Window——Install New SoftWare 2.找到相应插件卸载即可
- 使用vue2.0创建的项目的步骤
1.由于vue项目依赖 node.js npm 需要先安装. 若没有请先安装,请百度 //检查是否有node.js npm vue win+r 输入cmd 输入node -v 回车 会出 ...
- Unity中激活子物体
void GetChildrenAndSetActive() { Transform[] imageTargetObjects = GetComponentsInChildren<Transfo ...
- Asp.net core logging 日志
1 基本概念 Dotnet core 一个重要的特征是 Dependency injection ,中文一般是依赖注入,可以简单理解为一个集合,在应用程序启动时,定义各种具体的实现类型并将其放到集合中 ...
- [Firefox附加组件]0001.入门
Firefox 火狐浏览器,拥有最快.最安全的上网体验,并且火狐拥有超过一万个的 扩展(add-ons),提供各种不同的扩展功能,您可以简单的下载.安装这些扩展以增强您的火狐功能,帮助您更好.更个性化 ...