性能测试分析调优必备的java虚拟机知识

Java虚拟机 

Java虚拟机(Java Virtual Machine,简称JVM)是一种用于执行Java字节码的虚拟计算机。它是Java平台的关键组成部分,负责将Java源代码编译为可在不同计算机体系结构上执行的字节码。

JVM起到了中间层的作用,使得Java程序可以在不同的操作系统和硬件上运行,实现了“一次编写,到处运行”的特性。JVM提供了内存管理、垃圾回收、安全机制、线程管理等功能,极大地简化了Java程序的开发和部署。

当你运行一个Java程序时,JVM将Java字节码加载到内存中,并逐行解释执行或即时编译为机器码执行。这种解释和编译的组合方式使得Java具有良好的跨平台性和高效的性能表现。

总之,Java虚拟机是Java程序的运行平台,它使得Java语言具备了跨平台、高效、安全等特性。

这个虚拟机的版本是sun公司的Hotspot。

参考:

测试工程师都能看懂的Jvm知识 上 (qq.com)

测试工程师都能看懂的Jvm知识 中 (qq.com)

测试工程师都能看懂的Jvm知识 下 (qq.com)

自动内存管理

 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域

 

堆Heap

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存 。

Java堆可以处于物理上不连续的内存空间中

按照可扩展来实现的(通过-Xmx和-Xms控制)。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。

堆内存分类

Java堆中还可以细分为:新生代和老年代;再细致一点的有Eden空间、From Survivor空间、To Survivor空间等

这样区分,是为了采用不同的回收算法来对内存进行回收。

 

jvm垃圾回收

堆内存资源宝贵且有限,如果堆积大量这种对象,势必会导致内存泄露、甚至溢出,那怎么办?垃圾回收啊,jvm自带一个垃圾回收线程,不断检查一些没有被局部变量、静态变量、或一些常量引用实例对象,标记这些对象为 可回收“垃圾”,定期清理掉,节省内存资源。

Young Gc就是发生在新时代的垃圾回收,Major Gc就是发生在老年代的垃圾回收,又称OldGc,Full Gc是发生在新时代、老年代、永久代等区域的垃圾回收,full就是全部的意思。不管是Young Gc、Full Gc还是其他Gc,都会造成 Stop the World 现象,都会导致系统卡顿,只是每个Gc造成的卡顿时间不同。

内存溢出OutOfMemoryError

除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(下文称OOM)异常的可能

OutofMemortError

OutOfMemoryError是Java程序在试图分配更多内存时可能会遇到的一种错误。这通常发生在程序尝试创建大量对象或大型对象,而Java虚拟机(JVM)无法为它们分配足够的内存空间时。

有几种可能的原因可能导致OutOfMemoryError:

JVM的堆内存不足:这是最常见的原因。Java程序在运行时会在堆内存中创建对象。如果堆内存不足,JVM会抛出OutOfMemoryError。
永久代(PermGen)或元空间(Metaspace)空间不足:永久代是存储类的元数据和静态变量的地方,元空间是Java 8引入的替代永久代的概念。如果这两个区域的空间不足,也会抛出OutOfMemoryError。
栈深度过大:每个线程在JVM中都有自己的栈,用于存储局部变量和方法调用。如果栈的深度太大,超过了JVM的限制,也会抛出OutOfMemoryError。

解决OutOfMemoryError的方法: 

增加JVM的堆内存大小:可以通过调整启动JVM的参数来实现,例如使用-Xmx参数设置最大堆内存大小。
优化代码:避免创建大量的对象或大型对象,尽量复用对象,减少内存消耗。
检查是否存在内存泄漏:内存泄漏可能会导致程序在长时间运行后逐渐消耗越来越多的内存。使用Java的内存分析工具(如VisualVM、MAT等)可以帮助检测内存泄漏。
使用更适合的数据结构或算法:有些数据结构或算法可能会比其他的更消耗内存。尝试使用更节省内存的数据结构或算法可能有助于解决问题。
调整JVM的其他内存参数:例如,调整永久代或元空间的大小,或调整栈的大小等。

注意:在处理OutOfMemoryError时,最重要的是确定问题的原因。这可能需要使用内存分析工具,或者仔细审查代码以确定是否存在内存泄漏或其他问题。仅仅增加JVM的内存大小可能只是暂时的解决方案,如果问题的根本原因没有得到解决,问题可能会再次出现。 

Java堆溢出

Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。下面示例代码限制Java堆的大小为20MB,不可扩展(将堆的最小值-Xms参数与最大值-Xmx参数设置为一样即可避免堆自动扩展),通过参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析

HeapDumpOnOutOfMemoryError是Java虚拟机(JVM)的一个参数,当JVM发生OutOfMemoryError时,它会自动生成一个堆转储文件(Heap dump file),这个文件通常用于后续的内存分析。

在JVM参数中加入-XX:+HeapDumpOnOutOfMemoryError,例如:java -XX:+HeapDumpOnOutOfMemoryError -jar yourApp.jar,当程序运行发生OutOfMemoryError时,会在项目目录下生成一个名为java_pid<pid>.hprof的堆转储文件(其中<pid>是Java进程的ID)。

需要注意的是,这种做法并不能解决OutOfMemoryError问题本身,只是提供了一种方便的途径进行后续的内存分析,以找出内存耗尽的原因。

import java.util.List;
import java.util.ArrayList;
public class HeapOOM {static class OOMObject {}public static void main(String[] args) {List<OOMObject> list = new ArrayList<OOMObject>();while (true) {list.add(new OOMObject());}}
}

VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

 

在idea的edit configurations配置参数。

运行方法

可以看到发生了内存溢出。

Java堆内存的OOM异常是实际应用中常见的内存溢出异常情况。当出现Java堆内存溢出时,异常堆栈信息“java.lang.OutOfMemoryError”会跟着进一步提示“Java heap space”。

要解决这个区域的异常,一般的手段是先通过内存映像分析工具(如Eclipse Memory Analyzer)对Dump出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要先分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)

如果是内存泄露,可进一步通过工具查看泄露对象到GC Roots的引用链。于是就能找到泄露对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们的。掌握了泄露对象的类型信息及GC Roots引用链的信息,就可以比较准确地定位出泄露代码的位置。如果不存在泄露,换句话说,就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的堆参数(-Xmx与-Xms),与机器物理内存对比看是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。

垃圾回收

垃圾收集(Garbage Collection,GC)

Java堆和方法区是垃圾回收器所关注的内存区域。

GC需要完成的3件事情

哪些内存需要回收?

什么时候回收?

如何回收?

可达性分析算法

可达性分析(Reachability Analysis)来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的

垃圾回收算法

标记-清除算法

复制算法

标记-整理算法

分代收集算法

一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记—清理”或者“标记—整理”算法来进行回收。

垃圾收集器

内存分配策略

对象优先在Eden分配大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。

大对象直接进入老年代所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组(笔者列出的例子中的byte[]数组就是典型的大对象

长期存活的对象将进入老年代

内存回收与垃圾收集器在很多时候都是影响系统性能、并发能力的主要因素之一,虚拟机之所以提供多种不同的收集器以及提供大量的调节参数,是因为只有根据实际应用需求、实现方式选择最优的收集方式才能获取最高的性能。没有固定收集器、参数组合,也没有最优的调优方法,虚拟机也就没有什么必然的内存回收行为。因此,学习虚拟机内存知识,如果要到实践调优阶段,那么必须了解每个具体收集器的行为、优势和劣势、调节参数

本文内容摘自《深入理解java虚拟机:JVM高级特性与最佳实践》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141460.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

IP转地理位置:探讨技术与应用

IP地址是互联网上设备的唯一标识符&#xff0c;而将IP地址转换为地理位置信息是网络管理、安全监控和市场定位等领域中的一项重要任务。本文将深入探讨IP转地理位置的技术原理和各种应用场景。 IP地址与地理位置 IP地址&#xff08;Internet Protocol Address&#xff09;是一…

面试官:你了解axios的原理吗?有看过它的源码吗?

面试官&#xff1a;你了解axios的原理吗&#xff1f;有看过它的源码吗&#xff1f; 一、axios的基本使用 关于 axios 的基本使用&#xff0c;上篇文章已经有所涉及&#xff0c;这里再稍微回顾一下&#xff1a; 发送请求 import axios from axios;axios(config) // 直接传入…

一百八十六、大数据离线数仓完整流程——步骤五、在Hive的DWS层建动态分区表并动态加载数据

一、目的 经过6个月的奋斗&#xff0c;项目的离线数仓部分终于可以上线了&#xff0c;因此整理一下离线数仓的整个流程&#xff0c;既是大家提供一个案例经验&#xff0c;也是对自己近半年的工作进行一个总结。 二、数仓实施步骤 &#xff08;五&#xff09;步骤五、在Hive的…

《从菜鸟到大师之路 MySQL 篇》

《从菜鸟到大师之路 MySQL 篇》 数据库是什么 数据库管理系统&#xff0c;简称为DBMS&#xff08;Database Management System&#xff09;&#xff0c;是用来存储数据的管理系统。 DBMS 的重要性 无法多人共享数据 无法提供操作大量数据所需的格式 实现读取自动化需要编程…

docker安装使用xdebug

docker安装使用xdebug 1、需要先安装PHP xdebug扩展 1.1 到https://pecl.php.net/package/xdebug下载tgz文件&#xff0c;下载当前最新稳定版本的文件。然后把这个tgz文件放到php/extensions目录下&#xff0c;记得install.sh中要替换解压的文件名&#xff1a; installExtensio…

Vue 组件开发总结

Vue 组件开发思路 1. 组件划分 首先&#xff0c;你需要明确定义组件的划分。将大型界面划分为小型、可重用的组件是一个关键步骤。这有助于提高代码的可维护性和可复用性。 2. 组件设计 在设计组件时&#xff0c;考虑组件的输入&#xff08;props&#xff09;和输出&#xf…

数据库常用指令

检查Linux系统是否已经安装了MySQL&#xff1a; sudo service mysql start

手把手教你使用PLSQL远程连接Oracle数据库【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

浅谈智能照明控制系统在体育馆中的应用

【摘要】在社会经济日益发展的今天&#xff0c;人们的物质文化水平都有着不同程度上的提高。与此同时人们更加追求高质量的工作和生活环境。照明在现代化的多功能体育场馆中是非常重要的一个环节。智能化的照明控制系统能够根据环境的变化以及客户的需求等条件来自动调节照明系…

数据中心市场现状及发展趋势分析

随着数字化转型的加速&#xff0c;数据中心在中国的市场需求日益增长。本文将分析2023年中国数据中心市场的现状&#xff0c;并探讨其未来发展趋势。 一、2023年中国数据中心市场现状 市场规模&#xff1a;2023年中国数据中心市场的规模已经相当庞大&#xff0c;达到了数百亿美…

Bigemap如何查看历史影像

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 很多人都在寻找历史影像图&#xff0c;这块的需求是非常大&#xff0c;历史影像一般可以用于历史地貌的变迁分析&#xff0c;还原以前的生态场景&#xff0c;对范围面积…

由于找不到MSVCP140.dll,无法继续执行代码,重新安装程序可能会解决此问题的”修复方案

在Windows操作系统中&#xff0c;msvcp140.dll是一个非常重要的动态链接库文件&#xff0c;它是Microsoft Visual C 2015 Redistributable的一部分。这个文件主要用于支持许多应用程序的正常运行&#xff0c;例如Microsoft Office、SQL Server等。当计算机上缺少msvcp140.dll文…

Django(21):使用Celery任务框架

目录 Celery介绍Celery安装Celery使用项目文件和配置启动Celery编写任务调用异步任务查看任务执行状态及结果 设置定时和周期性任务配置文件添加任务Django Admin添加周期性任务启动任务调度器beat Flower监控任务执行状态Celery高级用法与注意事项给任务设置最大重试次数不同任…

ChatGPT详细搭建教程+支持AI绘画

一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统&#xff1f;小编这里写一个详细图文教程吧&#x…

eCognition易康操作教程(一):如何利用eCognition易康软件进行影像分割之棋盘分割、四叉树分割、光谱差异分割

一、新建工程 使用eCognition新建工程ImageSegmentation&#xff0c;加载影像数据&#xff0c;并编辑图层名称&#xff0c;将Layer 1、Layer 2、Layer 3、Layer 4的 Layer Alias 分别改为 Blue、Green、Red、如图1-1&#xff0c;图1-2所示&#xff1a; 图 1-1 图 1-2 设置加载…

大型监控网络设备架构

IT监控架构的功效日益突出&#xff0c;已成为企业信息化建设不可或缺的一部分。本文将详细介绍IT监控架构的含义、构成、功能及其在公司中的应用。 IT监控架构的含义是什么&#xff1f; 简单来说&#xff0c;IT监控架构就是利用一系列技术和方法对公司的IT系统进行全方位的监控…

unable to access xxxx: Failed to connect to xxxx

问题&#xff1a; 1、GitLab仓库加上双重验证后&#xff0c;设置GIt得 Manage Remotes时报错 unable to access xxxx: Failed to connect to xxxx SSL certificate problem:self signed certificate 解决 1、返回前面得操作步骤检查了一遍 没有问题 2、最后尝试一些方法解…

微信收款码费率0.38太坑了

作为一个有多年运营经验的商家&#xff0c;我本人在申请收款功能时曾经走过了不少弯路。我找遍了市面上的知名的支付公司&#xff0c;但了解到的收款手续费率通常都在0.6左右&#xff0c;最低也只能降到0.38。这个过程吃过不少苦头。毕竟&#xff0c;收款功能是我们商家的命脉&…

java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

.NET 8 性能比 .NET 7 大幅提升

微软 .NET 开发团队的工程师 Stephen Toub 发表博客《Performance Improvements in .NET 8》&#xff0c;详细介绍了 .NET 8 中的性能改进。 介绍了 .NET 8 的性能表现&#xff0c;包括 JIT、原生 AOT、VM、GC、Mono、线程、文件 I/O、网络、JSON 处理、日志等。 .NET 7 was s…