This commit is contained in:
estom
2024-04-10 20:36:29 +08:00
parent f918e12304
commit 0366489c3a
5 changed files with 2048 additions and 1 deletions

View File

@@ -17,6 +17,8 @@ OOM全称“Out Of Memory”翻译成中文就是“内存用完了”
而在Java语言中由于存在了垃圾自动回收机制所以我们一般不用去主动释放不用的对象所占的内存也就是理论上来说是不会存在“内存泄露”的。但是如果编码不当比如将某个对象的引用放到了全局的Map中虽然方法结束了但是由于垃圾回收器会根据对象的引用情况来回收内存导致该对象不能被及时的回收。如果该种情况出现次数多了就会导致内存溢出比如系统中经常使用的缓存机制。Java中的内存泄露不同于C++中的忘了delete往往是逻辑上的原因泄露。
# 3.OOM类型
JVM内存模型
@@ -61,4 +63,9 @@ dump堆内存信息后需要对dump出的文件进行分析从而找到OOM
涉及到的虚拟机的技术或者工具,往往需要考虑到虚拟机规范以及不同的虚拟机实现。尤其是针对虚拟机调优时,往往需要针对虚拟机在某些方面的实现策略来考虑,比如,不同的虚拟机的垃圾回收算法是不一样的,而这直接影响了虚拟机某些参数的设置,以达到虚拟机的最佳性能。
而针对JVM运行时的分析与诊断则需要掌握分析基本方法针对具体情况运用虚拟机的原理具体分析。一句话水很深啊。
而针对JVM运行时的分析与诊断则需要掌握分析基本方法针对具体情况运用虚拟机的原理具体分析。一句话水很深啊。
## 6. Mat使用简介
MAT全称Memory Analysis Tools是一款分析Java堆内存的工具可以快速定位到堆内泄漏问题。该工具提供了两种使用方式一种是插件版可以安装到Eclipse使用另一种是独立版可以直接解压使用。

View File

@@ -0,0 +1,503 @@
## 1 为什么性能测试
### 概述
软件性能测试是一种非功能性测试,其中应用程序的性能在预期或更高负载下进行评估。
进行性能测试以测量系统的不同性能属性,如响应时间(速度),可靠性,资源使用,可扩展性,各种负载条件下的稳定性等。
### 基本功能
JMeter也称为“Apache JMeter”它是一个开源的100%基于Java的应用程序带有图形界面。 它旨在分析和衡量Web应用程序和各种服务的性能和负载功能行为。
JMeter主要用于测试Web应用程序或FTP应用程序但目前它适用于功能测试JDBC数据库连接Web服务通用TCP连接和OS本机进程。 您可以执行各种测试活动如性能负载压力回归和功能测试以便针对您的Web服务器获得准确的性能指标。
* Web Services - SOAP / XML-RPC
* Web - HTTP, HTTPS sites web 1.0 web 2.0 (ajax, flex 和 flex-ws-amf)
* 通过JDBC驱动程序的数据库
* 目录 - LDAP
* 通过JMS面向消息传递的服务
* 服务 - POP3, IMAP, SMTP
## 2 使用教程
### 基本界面
![](https://www.yiibai.com/uploads/images/2018/08/01/171458_22860.png)
### 核心概念
> https://www.yiibai.com/jmeter/build-jmeter-test-plan.html
* 测试计划TestPlans
* 线程组Thread Groups
* 采样器Samplers
* 监听器
* 配置文件
* 监听器
* 配置文件
* 监听器
* 配置文件
![img](https://www.yiibai.com/uploads/article/2018/08/02/160226_93320.png)
测试计划可以将测试计划可视化为用于运行测试的JMeter脚本。测试计划由测试元素组成例如线程组逻辑控制器样本生成控制器监听器定时器断言和配置元素。每个测试计划中至少应有一个线程组。 我们可以根据要求添加或删除元素。
* JMeter文件或测试计划以 `.JMX`扩展文件的形式保存。JMX是一种基于开放测试的格式它使测试计划能够在文本编辑器中启动。
* “测试计划(Test plan)”节点包含测试计划的名称和用户定义的变量。当您在测试计划的多个部分中有重复值时,可使用用户定义变量,它提供了灵活性。
![1712477758187](image/04Jmeter压测工具/1712477758187.png)
线程组线程组表示JMeter在测试期间将使用的线程组。 线程组元素是任何测试计划的起点。
* 设置线程数。
* 设置加速期。
* 设置执行测试的次数。
![](https://www.yiibai.com/uploads/images/2018/08/02/170253_30401.png)
控制器—采样器采样器是允许JMeter将特定类型的请求发送到服务器的组件。它模拟用户对目标服务器的页面的请求。
* 采样器是必须将组件添加到测试计划中的因为它只能让JMeter知道需要将哪种类型的请求发送到服务器。 请求可以是HTTPHTTP(s)FTPTCPSMTPSOAP等。
![](https://www.yiibai.com/uploads/images/2018/08/02/170925_11078.png)
控制器-逻辑控制器:逻辑控制器可帮助您控制线程中采样器处理顺序的流程。 它还可以更改来自其子元素的请求的顺序。
* 运行时控制器
* IF控制器
* 事务控制器
* 录音控制器
* 简单控制器
* while控制器
* Switch控制器
* ForEach控制器
* 模块控制器
* 包括控制器
* 循环控制器
* 仅一次控制器
* 交错控制器
* 随机控制器
* 随机顺序控制器
* 吞吐量控制器
![](https://www.yiibai.com/uploads/images/2018/08/02/171522_14436.png)
监听器性能测试就是以各种形式分析服务器响应然后将其呈现给客户端。当JMeter的采样器组件被执行时监听器提供JMeter收集的关于那些测试用例的数据的图形表示。它便于用户在某些日志文件中以表格图形树或简单文本的形式查看采样器结果。监听器可以在测试的任何地方进行调整直接包括在测试计划下。JMeter提供了大约15个监听器但主要使用的是表树和图形。
* 图表结果
* 样条曲线可视化器
* 断言结果
* 简单的数据编写者
* 监控结果
* 分布图(alpha)
* 聚合图
* 梅勒展示台
* BeanShell监听器
* 总结报告
* 示例结果保存配置
* 图表完整结果
* 查看结果树
* 汇总报告
* 查看表格中的结果
![](https://www.yiibai.com/uploads/article/2018/08/02/171858_59718.png)
配置配置元素的工作与采样器的工作类似。但是它不发送请求但它允许修改采样器发出的请求。这是一个简单的元素您可以在其中收集所有采样器的关联配置值如webserver的主机名或数据库URL等。配置元素只能从放置元素的分支内部访问。
* Java请求默认值
* LDAP请求默认值
* LDAP扩展请求默认值
* 密钥库配置
* JDBC连接配置
* 登录配置元素
* CSV数据集配置
* FTP请求默认值
* TCP采样器配置
* 用户定义的变量
* HTTP授权管理器
* HTTP缓存管理器
* HTTP Cookie管理器
* HTTP代理服务器
* HTTP请求默认值
* HTTP标头管理器
* 简单的配置元素
* 随机变量
![](https://www.yiibai.com/uploads/article/2018/08/02/175205_28314.png)
预处理器元素在采样器发出请求之前执行,如果预处理器附加到采样器元素,那么它将在该采样器元素运行之前执行。
预处理器元素用于在运行之前修改样本请求的设置,或更新未从响应文本中提取的变量。
以下是JMeter提供的所有预处理器元素的列表:
* JDBC预处理器
* JSR223预处理器
* RegEx用户参数
* BeanShell预处理器
* BSF预处理器
* HTML链接解析器
* HTTP URL重写修饰符
* HTTP用户参数修饰符
* 用户参数
![](https://www.yiibai.com/uploads/images/2018/08/02/175631_46005.png)
在发出采样器请求之后执行后处理器元素。 如果后处理器连接到Sampler元素那么它将在该sampler元素运行之后执行。
后处理器最常用于处理响应数据,例如,为了将来目的而提取特定值。
下面给出了JMeter提供的所有后处理器元素的列表
* CSS/JQuery抽取器
* BeanShell后处理器
* JSR223后处理器
* JDBC后处理器
* 调试后处理器
* 正则表达式提取器
* XPath抽取器
* 结果状态操作处理程序
* BSF后处理器
![](https://www.yiibai.com/uploads/article/2018/08/02/180931_39141.png)
### 启动命令
在服务器上一版使用命令行启动测试脚本。
使用命令行启动 JMeter 时,可以通过命令行参数来配置 JMeter 的运行方式,比如设置测试计划文件、日志文件、执行模式以及各种系统属性等。以下是一些常用的 JMeter 命令行启动参数:
* `-n`:指定 JMeter 以**非图形界面模式**运行,适用于批量运行或分布式测试。
* `-t [测试计划.jmx]`:指定 JMeter 测试计划文件的路径。
* `-l [结果文件.jtl]`:指定 JMeter 测试结果的输出文件路径。
* `-j [日志文件.log]`:指定 JMeter 运行日志的输出文件路径。
* `-r`:告诉 JMeter 的 Master 连接到定义在 `jmeter.properties` 文件中的远程 Slave 服务器。只有在 `-n` 也被指定时才能使用 `-r`
* `-R [逗号分隔的服务器列表]`:指定远程 Slave 服务器的列表,用于分布式测试。如 `-R 192.168.0.1,192.168.0.2`
* `-d [目录]`:指定 JMeter 的“起始目录”,即 JMeter 将在该目录下查找用户类路径和插件。
* `-p [属性文件]`:指定 JMeter 属性文件的路径,通常是 `jmeter.properties` 文件。
* `-q [额外属性文件]`:指定一个额外的 JMeter 属性文件,可以用于覆盖默认的属性设置。
* `-J[属性名]=[值]`:直接在命令行中设置某个 JMeter 属性的值,如 `-JthreadNum=10` 设置属性 `threadNum` 的值为 10。
* `-G[属性名]=[值]`:用于分布式测试,给远程的 Slave 服务器设置全局属性。
* `-e`:在测试完成后以图形界面模式打开生成的报告分析数据。
* `-o [输出目录]`:指定输出文件夹,用于存放使用 `-e` 参数生成的 HTML 报告。如果文件夹不存在JMeter 将会创建它。
* `-H [代理主机名]``-P [代理端口]`:配置 JMeter 使用代理服务器,如 `-H my.proxy.server -P 8000` 指定代理服务器。
* `-u``-a`指定订阅和发布的令牌JMeter 5.0 引入)。
典型的启动命令如下
jmeter -n -t /path/to/your/testplan.jmx -l /path/to/resultsfile.jtl
## 3 使用实例
web的使用实例
https://www.yiibai.com/jmeter/jmeter-web-test-plan.html
## 4 自定义Jmeter采样器
<table>
<thead>
<tr>
<th>步骤</th>
<th>动作</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>创建一个Java类并继承<code>AbstractJavaSamplerClient</code></td>
</tr>
<tr>
<td>2</td>
<td>实现<code>setupTest</code>方法,用于初始化</td>
</tr>
<tr>
<td>3</td>
<td>实现<code>runTest</code>方法,用于执行具体的请求</td>
</tr>
<tr>
<td>4</td>
<td>实现<code>teardownTest</code>方法,用于清理资源</td>
</tr>
<tr>
<td>5</td>
<td>编译并将生成的jar文件放入JMeter的lib/ext目录下</td>
</tr>
<tr>
<td>6</td>
<td>在JMeter中创建一个新的线程组</td>
</tr>
<tr>
<td>7</td>
<td>添加一个<code>Java Request</code>到线程组中,并设置相应的参数</td>
</tr>
<tr>
<td>8</td>
<td>运行测试,查看结果</td>
</tr>
</tbody>
</table>
#### 步骤 1: 创建一个Java类并继承 `AbstractJavaSamplerClient`
引入对应的依赖
```xml
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>4.0</version>
</dependency>
```
首先我们需要创建一个Java类并继承 `AbstractJavaSamplerClient`。这个类将成为我们自定义Sampler的入口点。
1、setupTest 用来做一些初始化的操作,每一线程只会调用该方法一次。
2、teardownTest 用来做一些清理的操作,每一线程只会调用该方法一次。
3、getDefaultParameters 设置sample的参数以及默认值这个方法设置的参数会显示在Java request组件的界面上。
4、runTest 这个方法就是sample的核心方法每次迭代都会调用并且返回SampleResult对象。由于该方法是抽象方法所以自定的sample一定要实现该方法其他方法可根据情况选择是否重写。
```java
package lym.iflytek.mt_scylla;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
public class TestSample extends AbstractJavaSamplerClient {
private IatDemo iat;#业务类具体代码不再贴出来
public Arguments getDefaultParameters() {
/*
这个方法由JMeter调用添加的Arguments参数会在界面上展示出来可以设置默认值。
* */
Arguments arg = new Arguments();
arg.addArgument("addr", "");
arg.addArgument("appid", "");
arg.addArgument("token", "");
arg.addArgument("rate", "");
arg.addArgument("filePath", "");
arg.addArgument("printLog", "false");
arg.addArgument("encoding", "utf-8");
arg.addArgument("costTimeType", "3");
return arg;
}
public void setupTest(JavaSamplerContext context) {
/*进行初始化操作,每一个线程只执行一次*/
String addr = context.getParameter("addr");
String appid = context.getParameter("appid");
String token = context.getParameter("token");
String rate = context.getParameter("rate");
String printLog = context.getParameter("printLog");
String costTimeType = context.getParameter("costTimeType");
iat = new IatDemo(addr, appid, token, rate, printLog, costTimeType);
System.out.println(Thread.currentThread().getName()+":初始完成");
}
public void teardownTest(JavaSamplerContext context){
/*做一些清理操作,每个线程只执行一次*/
try {
iat.UninitializeEx();
System.out.println(Thread.currentThread().getName()+":逆初始化完成");
} catch (IflytekException e) {
getNewLogger().error(e.getMessage(), e);
}
}
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
/*每次迭代都会调用并且返回SampleResult对象该对象保存了每次运行的执行结果*/
String filePath = javaSamplerContext.getParameter("filePath");
String encoding = javaSamplerContext.getParameter("encoding");
String costTimeType = javaSamplerContext.getParameter("costTimeType");
#SampleResult 用来保存每次运行的结果以便JMeter进行数据统计
SampleResult sampleResult = new SampleResult();
#通过参数控制运行时间的统计范围如果你的业务没那么复杂
#完全可以在runTest开始时设置开始时间方法结束时设置结束时间
if (costTimeType.equals("1")) {
sampleResult.sampleStart();#设置运行的开始时间
}
try {
String allresult = iat.start(filePath, sampleResult);
sampleResult.setSamplerData(filePath);#设置输入数据
sampleResult.setDataType(SampleResult.TEXT);#设置数据类型
sampleResult.setResponseData(allresult, encoding);#设置sample接收到的数据
sampleResult.setSuccessful(true);#设置sample执行结果
sampleResult.setResponseCodeOK();#设置sample执行状态码
} catch (Exception e) {
sampleResult.setSuccessful(false);
sampleResult.setResponseCode("500");
sampleResult.setResponseMessage(e.getMessage());
getNewLogger().error(e.getMessage(), e);
}
if (costTimeType.equals("1")) {
#设置运行的结束时间结束时间-开始时间就是整个sample的运行时间
#JMeter就是用这个时间来计算平均响应时间的可以根据实际情况设置在不同的位置
sampleResult.sampleEnd();
}
if (sampleResult.getStartTime() == 0) {
sampleResult.sampleStart();
}
if (sampleResult.getEndTime() == 0) {
sampleResult.sampleEnd();
}
return sampleResult;
}
public static void main(String[] args) {
IflytekSample sample = new IflytekSample();
Arguments arg = new Arguments();
arg.addArgument("addr", "192.168.0.1:1234");
arg.addArgument("appid", "00000000");
arg.addArgument("token", "11111111");
arg.addArgument("rate", "41000");
arg.addArgument("filePath", "1.wav");
arg.addArgument("printLog", "true");
arg.addArgument("costTimeType", "2");
JavaSamplerContext javaSamplerContext = new JavaSamplerContext(arg);
sample.setupTest(javaSamplerContext);
SampleResult sampleResult = sample.runTest(javaSamplerContext);
System.out.println(sampleResult.getResponseDataAsString());
sample.teardownTest(javaSamplerContext);
}
```
#### 步骤 2: 实现 `setupTest`方法
`setupTest`方法在每个线程开始之前执行,用于初始化一些资源或设置。在这个方法中,你可以进行一些预处理的操作。
```java
@Override
public void setupTest(JavaSamplerContext context) {
// TODO: 初始化操作
}
1.2.3.4.
```
#### 步骤 3: 实现 `runTest`方法
`runTest`方法是实际执行请求的地方。在这个方法中你可以使用各种HTTP或其他类型的客户端库来发送请求并处理响应。
```java
@Override
public SampleResult runTest(JavaSamplerContext context) {
SampleResult result = new SampleResult();
result.sampleStart(); // 标记请求的开始时间
// TODO: 执行实际的请求操作
result.sampleEnd(); // 标记请求的结束时间
return result;
}
```
#### 步骤 4: 实现 `teardownTest`方法
`teardownTest`方法在每个线程结束之后执行,用于清理资源或做一些收尾的工作。
```java
@Override
public void teardownTest(JavaSamplerContext context) {
// TODO: 清理操作
}
```
#### 步骤 5: 编译并将生成的jar文件放入JMeter的lib/ext目录下
完成以上步骤后我们需要将代码编译成jar文件并将该文件放入JMeter的lib/ext目录下。这样JMeter就能够找到并加载我们自定义的Sampler。
#### 步骤 6: 在JMeter中创建一个新的线程组
在JMeter中我们需要创建一个新的线程组来运行我们的测试。线程组表示一组并发的用户可以设置线程数、循环次数等参数。
#### 步骤 7: 添加一个 `Java Request`到线程组中,并设置相应的参数
在线程组中,我们需要添加一个 `Java Request`。在该请求中我们需要设置一些参数例如类名、方法名等以告诉JMeter我们要运行哪个自定义的Sampler。
#### 步骤 8: 运行测试,查看结果
最后,我们可以运行测试并查看结果。在结果树中,我们可以看到每个请求的响应时间、错误率等信息。
## 5 创建Jmeter集群
### 原理
1、Jmeter分布式测试时选择其中一台作为控制机(Controller),其它机器做为代理机(Agent)。
2、执行时Controller会把脚本发送到每台Agent上Agent 拿到脚本后开始执行Agent执行时不需要启动Jmeter只需要把jmeter-server.bat文件打开它应该是通 过命令行模式来执行的。
3、执行后Agent会把结果回传给ControllerController会收集所有Agent的信息并汇总。
### Slave配置
配置Slave的地址名称。Jmeter/bin/jmeter.properties找到”remote_hosts=127.0.0.1”,把这一行修改为”remote_hosts=192.168.8.149:1099
```properties
# Remote Hosts - comma delimited
remote_hosts=127.0.0.1:1099
#remote_hosts=localhost:1099,localhost:2010
# RMI port to be used by the server (must start rmiregistry with same port)
server_port=1099
```
启动jmeter slave
```properties
jmeter-server
```
### Master配置
GUI方式可以通过配置文件决定连接的remote。Jmeter/bin/jmeter.properties找到”remote_hosts=127.0.0.1”,把这一行修改为”remote_hosts=192.168.8.1491099,192.168.8.17410991099是端口号可以随意自定义。如果有多台代理机这里需要把所有的代理机的IP地址和端口号都加入进来。
```properties
remote_hosts=192.168.8.149:1099,192.168.8.174:1099
```
命令行方式
```properties
jmeter -n -t Test.jmx -l test_results.csv -JserverAddr=123 -R remote_host1,remote_host2
```
### 其他问题
一个比较标准的参数解决方案如下:
```
Jserver.rmi.ssl.disable=true -Jjava.net.preferIPv4Stack=true -Jjava.net.preferIPv6Addresses=false -Jsearch_paths=/home/admin/run
```
配置user.properties关闭http用户校验
```properties
server.rmi.ssl.disable=true
```
配置system.properties中ipv4网络协议
```properties
java.net.preferIPv4Stack=true
java.net.preferIPv6Addresses=false
```

View File

@@ -0,0 +1,87 @@
引言
JvmJava虚拟机是Java语言的基石对于Java应用的性能至关重要。而Jvm启动参数的优化是提高Java应用性能的一个重要手段。本文将介绍Jvm启动参数的优化和一些示例帮助开发者更好地理解和优化Jvm的启动参数。
java启动参数共分为三类
其一是标准参数(-所有的JVM实现都必须实现这些参数的功能而且向后兼容
其二是非标准参数(-X默认jvm实现这些参数的功能但是并不保证所有jvm实现都满足且不保证向后兼容
其三是非Stable参数-XX此类参数各个jvm实现会有所不同将来可能会随时取消需要慎重使用
Jvm性能优化
Jvm性能优化是应用开发过程中关注的一个重要方面。通过优化Jvm启动参数可以显著提升Java应用的性能。以下是一些常见的Jvm性能优化参数
-Xms: 指定Jvm的初始堆大小。
-Xmx: 指定Jvm的最大堆大小。
-Xmn: 指定Jvm的年轻代堆大小。
-XX:MaxPermSize: 指定Jvm的永久代或元空间大小。
-XX:SurvivorRatio: 指定Jvm的年轻代中Eden区和Survivor区的比例。
-XX:+UseParallelGC: 使用并行垃圾回收器。
-XX:+UseConcMarkSweepGC: 使用并发标记-清除垃圾回收器。
内存管理
Jvm的内存管理对于Java应用的性能有着重要的影响。通过合理地管理Jvm的内存可以避免内存泄漏和过度的垃圾回收。以下是一些与Jvm内存管理相关的启动参数
-XX:NewSize: 指定Jvm的年轻代的初始大小。
-XX:MaxNewSize: 指定Jvm的年轻代的最大大小。
-XX:NewRatio: 指定Jvm的年轻代和老年代的比例。
-XX:SurvivorRatio: 指定Jvm的年轻代中Eden区和Survivor区的比例。
-XX:MaxTenuringThreshold: 指定Jvm对象的年龄阈值。
垃圾回收
垃圾回收是Jvm中的重要子系统对于Java应用的性能和稳定性至关重要。通过选择合适的垃圾回收器和调整相关参数可以有效提升Jvm的垃圾回收性能。以下是一些与垃圾回收相关的启动参数
-XX:+UseSerialGC: 使用串行垃圾回收器。
-XX:+UseParallelGC: 使用并行垃圾回收器。
-XX:+UseConcMarkSweepGC: 使用并发标记-清除垃圾回收器。
-XX:+UseG1GC: 使用G1垃圾回收器。
-XX:ParallelGCThreads: 指定并行垃圾回收器的线程数。
-XX:ConcGCThreads: 指定并发垃圾回收器的线程数。
并发
并发是现代应用开发中普遍面临的挑战。Jvm提供了多种并发管理的选项可以通过调整相关参数来优化并发性能。以下是一些与Jvm并发管理相关的启动参数
-XX:ParallelGCThreads: 指定并行垃圾回收器的线程数。
-XX:ConcGCThreads: 指定并发垃圾回收器的线程数。
-XX:ThreadStackSize: 指定线程的堆栈大小。
-XX:+UseThreadPriorities: 启用线程优先级。
-XX:ThreadPriorityPolicy: 指定线程优先级策略。
示例
对于小型服务器配置如2核心4GB内存
对于小型的服务器配置如CPU为2核心内存为4GB的服务器JVM的配置可以考虑如下
java -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -jar app.jar
1
其中,参数 -Xms1024m 和 -Xmx1024m 分别表示JVM堆的最小值和最大值都为1024MB。一般情况下为了避免JVM因为动态调整堆大小产生的性能开销应该设置 -Xms 和 -Xmx 为相同值。
参数 -XX:PermSize=128m 和 -XX:MaxPermSize=256m 分别表示JVM永久代PermGen的初始大小为128MB最大值为256MB。永久代用于存放JVM加载的类和方法等静态数据如果服务器运行的Java应用需要加载大量的类就需要增大永久代的大小。
对于大型服务器配置
对于拥有更多CPU和内存的大型服务器JVM的配置则需要考虑不同的策略。例如对于一个拥有8核心16GB内存的服务器一个合理的JVM配置可能是
java -Xms8192m -Xmx8192m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:ParallelGCThreads=8 -XX:+UseConcMarkSweepGC -jar app.jar
1
在之前的基础上,我们增加了两个新的参数: -XX:ParallelGCThreads=8 和 -XX:+UseConcMarkSweepGC。
-XX:ParallelGCThreads=8 表示垃圾回收时的并行线程数为8。由于服务器有8个CPU核心设置并行线程数为CPU核心数可充分利用CPU资源进行垃圾回收。
-XX:+UseConcMarkSweepGC 表示使用CMSConcurrent Mark Sweep垃圾收集器。CMS是一款以获取最短回收停顿时间为目标的收集器适合对响应时间有高要求的服务器。大型服务器应用通常对性能要求较高因此选择CMS进行垃圾回收是合适的。
JVM参数解析
下面我们对前面提到的一些常用的JVM参数进行更详细的解析。
-Xmx 和 -Xms
-Xmx 和 -Xms 分别用于设置JVM堆的最大值和最小值。JVM的堆内存是用于存放Java对象的地方如果设置得太小会导致频繁的垃圾回收影响性能如果设置得太大有可能会导致长时间的GC停顿也会影响性能。因此需要根据服务的实际需求合理设置堆的大小。
-XX:PermSize 和 -XX:MaxPermSize
-XX:PermSize 和 -XX:MaxPermSize 用于设置JVM的永久代大小。永久代用于存放静态文件如Java类、方法等。如果服务器运行的应用需要加载大量的类就需要增大这两个参数的值。
-XX:ParallelGCThreads
-XX:ParallelGCThreads 用于设置并行垃圾回收器的线程数。这个参数的值一般设置为服务器CPU核心数这样可以充分利用CPU资源进行垃圾回收。
-XX:+UseConcMarkSweepGC
-XX:+UseConcMarkSweepGC 用于启用CMS垃圾回收器。CMS是一种以获取最短回收停顿时间为目标的收集器。大型服务器应用通常对性能要求较高因此选择CMS进行垃圾回收是合适的。
以上就是对JVM启动参数的一些基本介绍和优化策略希望能够对你有所帮助。记住无论是什么样的优化策略都需要通过实际的性能测试来进行验证和调整。
欢迎来访我的个人博客网站http://refblogs.com/ 可以互换友链
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接https://blog.csdn.net/qq_41389354/article/details/132044864

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB