String变量引起的Loadrunner资源泄漏

本文通过三种不同的字符串拼接方式对比分析了在压力测试环境下TPS下降的原因,揭示了String与StringBuilder对象创建位置的不同对性能的影响。


在压力测试中,通常碰到TPS平稳持续下降的现象,通常为负载机存在资源泄漏。一般有两种:1.连接数,2.JVM内存。本文就第2种类型进行测试和分析。



 

测试数据:

1.       String方式

public int action() throws Throwable {

lr.start_transaction("string");

 

String a = "The time is "+System.currentTimeMillis();

        String b = "The time is "+System.currentTimeMillis();

        String c = "The time is "+System.currentTimeMillis();

        String d = "The time is "+System.currentTimeMillis();

        String e = "The time is "+System.currentTimeMillis();

         lr.end_transaction("stringl", lr.AUTO);

 

写了个简单的给String变量赋值的代码,使用当前时间保证每次赋值都会变化。10个线程执行30分钟。

 

测试结果:

 

TPS持续下降:

 

YGC非常频繁:

同时CPU有走高的趋势

 

 

2.       StringBuilder方式一(New对象放在Action内)

 

//new放在Action中,每次迭代都new一个对象

 

         public int action() throws Throwable {

         lr.start_transaction("StringBuilder");

         StringBuilder bf1=new StringBuilder();

         StringBuilder bf2=new StringBuilder();

         StringBuilder bf3=new StringBuilder();

         StringBuilder bf4=new StringBuilder();

         StringBuilder bf5=new StringBuilder();

         bf1.append("The time is ");

        bf2.append("The time is ");

         bf3.append("The time is ");

         bf4.append("The time is ");

         bf5.append("The time is ");

         bf1.append(System.currentTimeMillis());

        bf2.append(System.currentTimeMillis());

         bf3.append(System.currentTimeMillis());

         bf4.append(System.currentTimeMillis());

         bf5.append(System.currentTimeMillis());

        bf1.setLength(0);

         bf2.setLength(0);

        bf3.setLength(0);

         bf4.setLength(0);

         bf5.setLength(0);

         lr.end_transaction("StringBuilder", lr.AUTO);

 

TPS

         

         TPS同样会下降

 

堆内存

 

 

 

3.       StringBuilder方式二(New对象放在Action外)

 

public class Actions

{

         StringBuilder bf1=new StringBuilder();

         StringBuilder bf2=new StringBuilder();

         StringBuilder bf3=new StringBuilder();

         StringBuilder bf4=new StringBuilder();

         StringBuilder bf5=new StringBuilder();

          

         public int init() throws Throwable {

 

                   return 0;

         }//end of init

 

 

         public int action() throws Throwable {

                  

         lr.start_transaction("StringBuilder");

 

         bf1.append("The time is ");

        bf2.append("The time is ");

         bf3.append("The time is ");

         bf4.append("The time is ");

         bf5.append("The time is ");

         bf1.append(System.currentTimeMillis());

        bf2.append(System.currentTimeMillis());

         bf3.append(System.currentTimeMillis());

         bf4.append(System.currentTimeMillis());

         bf5.append(System.currentTimeMillis());

        bf1.setLength(0);

         bf2.setLength(0);

        bf3.setLength(0);

         bf4.setLength(0);

         bf5.setLength(0);

         lr.end_transaction("StringBuilder", lr.AUTO);

 

                   return 0;

         }//end of action

 

 

TPS

TPS有轻微下降,但下降幅度比前两种方式要改善很多。

 

堆内存

从内存Dump中看到StringBuilder 实例有50 10用户,每个用户new 5个对象),但仍然有其他对象占很大比重,不清楚是否是Loadrunner本身所占用。

 



 

测试结果

1.       采用String类型给变量赋值,半小时看到TPS明显下降,并且负载机CPU有上升趋势,剩余内存有下降趋势;

2.       采用StringBuilder给变量赋值,new StringBuilder对象放在Action内(每次迭代均new一次),执行半小时,现象同String类型差不多;

3.       采用StringBuilder给变量赋值,new StringBuilder对象放在Action外,执行半小时,TPS有所下降,但下降趋势比前两个场景要小很多。

 

原因分析

1.       String 类型和 StringBuffer/StringBuilder 类型的主要性能区别其实在于 String 是不可变的对象,因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,(脚本中变量取当前时间,保证每次取值不同) new 对象需要消耗资源,并且当内存中无引用对象多了以后, JVM  GC 就会开始工作,导致GC频繁;

2.       由于本次压力测试与MAMBPS有一个共同特点,TPS比较高,因此可能是对象生成速度非常快,GC来不及回收,导致对象不断累积,并且GC越来越频繁导致了CPU上升和TPS逐渐下降,一般应用的TPS较低,因此有足够时间进行回收;

3.       另外,采用Loadrunner Java Vuser方式,LR本身也会生成一些对象,在高TPS下可能会出现对象来不及释放导致性能下降。

 

 
**项目名称:** 基于Vue.js与Spring Cloud架构的博客系统设计与开发——微服务分布式应用实践 **项目概述:** 本项目为计算机科学与技术专业本科毕业设计成果,旨在设计并实现一个采用前后端分离架构的现代化博客平台。系统前端基于Vue.js框架构建,提供响应式用户界面;后端采用Spring Cloud微服务架构,通过服务拆分、注册发现、配置中心及网关路由等技术,构建高可用、易扩展的分布式应用体系。项目重点探讨微服务模式下的系统设计、服务治理、数据一致性及部署运维等关键问题,体现了分布式系统在Web应用中的实践价值。 **技术架构:** 1. **前端技术栈:** Vue.js 2.x、Vue Router、Vuex、Element UI、Axios 2. **后端技术栈:** Spring Boot 2.x、Spring Cloud (Eureka/Nacos、Feign/OpenFeign、Ribbon、Hystrix、Zuul/Gateway、Config) 3. **数据存储:** MySQL 8.0(主数据存储)、Redis(缓存与会话管理) 4. **服务通信:** RESTful API、消息队列(可选RabbitMQ/Kafka) 5. **部署与运维:** Docker容器化、Jenkins持续集成、Nginx负载均衡 **核心功能模块:** - 用户管理:注册登录、权限控制、个人中心 - 文章管理:富文本编辑、分类标签、发布审核、评论互动 - 内容展示:首页推荐、分类检索、全文搜索、热门排行 - 系统管理:后台仪表盘、用户与内容监控、日志审计 - 微服务治理:服务健康检测、动态配置更新、熔断降级策略 **设计特点:** 1. **架构解耦:** 前后端完全分离,通过API网关统一接入,支持独立开发与部署。 2. **服务拆分:** 按业务域划分为用户服务、文章服务、评论服务、文件服务等独立微服务。 3. **高可用设计:** 采用服务注册发现机制,配合负载均衡与熔断器,提升系统容错能力。 4. **可扩展性:** 模块化设计支持横向扩展,配置中心实现运行时动态调整。 **项目成果:** 完成了一个具备完整博客功能、具备微服务典型特征的分布式系统原型,通过容器化部署验证了多服务协同运行的可行性,为云原生应用开发提供了实践参考。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值