用好单例设计模式,代码性能提升300%

news2024/12/30 3:18:19

目录

  • 一次请求执行流程
  • java代码是如何运行的?
  • 堆内存满了后怎么办?
  • 用单例模式如何优化系统性能?

大家好,今天给大家分享一个写代码的设计模式,就是我们最最耳熟能详的单例设计模式

可能很多人都听说过这个单例设计模式了,甚至都写的贼溜,但是今天给大家说说用这个这个单例设计模式,咱们是怎么把代码的性能大幅度提升的,单例模式跟代码性能的关系,恐怕很多兄弟还没认真研究过呢!

一次请求执行流程

首先我们先来看看什么叫做单例模式,要理解单例模式,我们就得先说说不用单例模式的时候,我们平时创建对象是怎么弄的。

平时创建对象这个简单吧,比如我们搞一个对外的web接口,然后再接口收到一个请求的时候,就创建一个对象。

这个伪代码如下:

@RestController("/user")
public class Controller {
  
  private UserService userService;
  
  @RequestMapping("/create")
  public Response create(CreateUserRequest request) {
    User user = new User(request);
    
    UserService userService = new UserService();
    userService.add(user);
    
    return Response.success();
  }
  
}
复制代码

上面那段代码极为的简单,假设你有一个Controller对外提供一个http接口,然后每次你通过浏览器发送一个创建用户的请求。

也就是针对/user/create这个url的请求,发送一个CreateUserRequest请求参数,代码里就会通过new关键字,搞出来一个User对象,然后再通过new关键字创建一个UserService组件来,接着把User对象交给UserService组件去插入这个用户数据到数据库里去,这段代码基本但凡是懂java的应该都能看懂。

但是这里有一个问题,大家知道每次处理请求的时候,这段代码运行他会干什么事情吗?

其实有最关键的点就是,他每次请求过来都会在内存里创建一个User对象和一个UserService对象,那这些对象是如何创建的呢?

java代码是如何运行的?

下面就得给大家来揭秘一下这个代码运行的底层原理了,首先呢,当我们启动一个java程序的时候,一定会启动一个jvm进程,比如说上面那段代码,你可能是通过spring boot这类框架用main方法启动的,也可能是把他打包以后放到tomcat里去运行的。

如果你是直接运行main方法来启动的,那么就会直接启动一个jvm进程,如果你是把代码打包以后放tomcat里运行的,那么tomcat自己本身就是一个jvm进程,如下图。

接着呢,其实你启动的JVM进程,会把你写好的代码加载到内存里来然后运行你写的代码,你的代码运行起来以后,他就可以干你希望他干的事情了,比如说接收浏览器发送的http请求,然后创建一些对象,插入数据库等等,如下图所示。

那么这个时候,有一个很关键的点,就是你的代码运行的时候用new User()和new UserService()创建出来的对象扔哪儿去了?

很简单,你的JVM进程是有一块自己的内存区域可以用的,而且就他可以用,这块区域叫做堆内存,这就类似于咱们自己家盖个小别墅,弄一块院子自己可以在里面种花种草一样,别人不能在你家院子里种黄瓜和大蒜,对不对,如下图。

那么接着呢,上面我们写的那段代码,大家一下,每次收到一个请求,都会创建一个User对象和一个UserService对象,对不对?

所以说,随着你不停的发送请求不停的发送请求,咱们的代码是不是会不停的创建对象不停的创建对象,然后咱们的堆内存里,**对象是不是就会变的越来越多,越来越多?

堆内存满了后怎么办?

那么我问大家一个问题,堆内存是一块内存空间,他是可以无限制的一直放入对象的吗?

当然不是了,当你的对象越来越多,太多的时候,就会把这块内存空间给塞满,塞满了以后他就放不下新的对象了,这个时候怎么办呢?

他会触发一个垃圾回收的动作,就是JVM进程自己偷偷摸摸开了一个垃圾回收线程,这个线程就专门盯着我们的堆内存,感觉他快满了,就把里面的对象清理掉一部分,这就叫做垃圾回收,如下图。

但是每次垃圾回收都有一个问题,他因为要清理掉一些对象,所以往往会在清理对象的时候,避免你再创建新的对象了,不然就跟你妈妈打扫你的房间一样,人家一边在打扫垃圾,结果你还不停的吃东西往地下扔垃圾,你妈妈不打你屁股才怪,对吧?所以一般垃圾回收的时候,会让JVM进程停止工作,别创建新的对象了,如下图。

那么在垃圾回收进行中,JVM进程停止运行的这个期间,是不是会导致一个问题,那就是你的用户发送过来的请求就没人处理了,没错,这个时候用户会感觉每次发送请求那是卡住,一直卡着没有返回,此时系统性能是处于一个极差的状态的,如下图。

用单例模式如何优化系统性能呢?

那么这个时候问题来了,回到这篇文章的主体,就是用单例模式如何优化系统性能呢?

其实针对上面的问题,很多小伙伴可能已经发现了,如果想要优化系统性能,有一个关键的点就是尽量创建少一些的对象,避免堆内存频繁的塞满,也就可以避免频繁的垃圾回收,更可以避免频繁的JVM进程停顿,进而避免系统请求频繁的卡顿无响应。

**那如何少创建一些对象呢?**单例模式就是一个很好的办法,对我们来说,完全可以让UserService这个对象就只创建一次,不要每次请求重复的创建他,让一个对象就创建一次,就是单例模式,单例模式有很多种写法,其中一种写法如下:

@RestController("/user")
public class Controller {
  
  private UserService userService;
  
  @RequestMapping("/create")
  public Response create(CreateUserRequest request) {
    User user = new User(request);
    
    UserService userService = UserSerivce.getInstance();
    userService.add(user);
    
    return Response.success();
  }
  
}

public class UserService {
  
  private UserService() {}
  
  private static class Singleton {
    static UserService userService = new UserService(); 
  }
  
  public static UserService getInstance() {
    return Singleton.userService;
  }
  
}
复制代码

大家可以看到上面的代码,我们在UserService中定义了一个私有化的静态内部类Singleton,在Singleton里定义了一个静态变量UserService对象,这样的话,Singleton这个类只会被加载一次,只有类加载的时候才会实例化一个静态变量UserService对象,后续每次通过getInstance()方法都是直接获取这唯一一个对象就可以了,不会重复创建对象。

这就是单例模式的一种写法,也是企业开发中最常用的一种写法,用了单例模式后,就可以大幅度降低我们创建的对象数量,避免堆内存频繁塞满,频繁垃圾回收,频繁JVM进程停顿影响请求性能,这样往往可以帮助我们更好的提升系统的性能。

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

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

相关文章

基于Dijkstra和A*算法的机器人路径规划(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 网络分析是GIS中非常重要的空间分析功能之一, 最短路径分析又是网络分析的核心算法, 该算法的效率决定了网络分析的功能和效率…

【CSDN】官方Markdown示例教程

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

Docker学习系列3:常用命令之容器命令

本文是Docker学习系列教程中的第三篇。前几篇教程如下: 「图文教程」Windows11下安装Docker Desktop 「填坑」在windows系统下安装Docker Desktop后迁移镜像位置 Docker学习系列1-如何安装docker? 【Docker学习系列】Docker学习2-docker设置阿里云镜像加速器 【Doc…

简单宠物网页设计作业 静态HTML动物介绍网页作业 DW宠物网站模板下载 大学生简单野生动物网页作品代码

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

ADSP-21569/ADSP-21593的开发入门(下)

开始调试 软硬件都准备好了,该插的JTAG头,2根usb线都插好了,我们就开始进入调试,首先是要搭建软件环境。 软件用的是CCES,这个软件是基于Eclipse的,基本操作跟他都一样,我们首先打开软件。 他…

阿里资深架构师钟华曰:中台战略思想与架构实战;含内部实施手册

​ 编辑 添加图片注释,不超过 140 字(可选) 最近在读一本书,叫做《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》,在写此文时本书还没有看完,因为担心如果把书全部看完后再来写这篇文…

Android轮播图控件com.github.pinguo-zhouwei:MZBannerView:v2.0.2

build.gradle 配置&#xff1a; dependencies { compile com.github.pinguo-zhouwei:MZBannerView:v2.0.2}xml布局&#xff1a; <com.zhouwei.mzbanner.MZBannerViewandroid:id"id/banner"android:layout_width"match_parent"android:layout_height&quo…

SpringBoot项目实现发布订阅模式,真的很简单

大家好&#xff0c;我是老三&#xff0c;在项目里&#xff0c;经常会有一些主线业务之外的其它业务&#xff0c;比如&#xff0c;下单之后&#xff0c;发送通知、监控埋点、记录日志…… 这些非核心业务&#xff0c;如果全部一梭子写下去&#xff0c;有两个问题&#xff0c;一…

python中的集合详解

目录 一.思考 二.集合 基本语法 集合的常用操作——修改 1.添加新元素 2.移除元素 3.从集合中随机取出元素 4.清空集合 5. 消除两个集合的差集 6.两个集合的合并 注意&#xff1a;集合的遍历 三.集合总结 一.思考 为什么使用集合&#xff1f; 我们目前接触到了列表、元…

php后端+JQuery+Ajax简单表单提交

通过ajax,如果从后端直接想前端返回数组,那前端收到的是一个‘Array’的字符串。所以,我比较习惯的是用json对象的格式。由后端通过json_encode()函数,把数组封装成对象,传递到前端;前端也以json的格式接收。这里用提交表单来举例说明。 页面显示如下: JQueryAjax.…

Kafka服务端参数配置

$KAFKA_HOME/config/server.properties文件中的配置 1、zookeeper.connect 该参数用于配置Kafka要连接的Zookeeper/集群的地址。它的值是一个字符串&#xff0c;使用逗号分隔Zookeeper的多个地址。Zookeeper的单个地址是host:port形式的&#xff0c;可以在最后添加Kafka在Zoo…

idea+docker+jenkins+git构建自动化部署java项目

ideadockerjenkinsgit构建自动化部署java项目 默认jenkins已经 安装jdk 9 和maven 3.5 用于 执行pom.xml 打包构建镜像 [rootECS40833040 ~]# mkdir -p /usr/local/jenkins [rootECS40833040 jenkins]# vim jenkins.sh #!/usr/bin/env bash app_name005-springboot docker …

2、JSP——配置Tomcat服务器

目录 1、下载Tomcat服务器 2、Tomcat服务器的安装 3、Tomcat的目录结构 4、配置Tomcat运行环境 4.1 右击此电脑--->属性--->高级系统设置--->环境变量 4.2 在系统变量(s)中新建--->CATALINA_HOME--->变量值为Tomcat压缩文件解压后的地址 4.3 在系统变量(s…

[附源码]计算机毕业设计线上评分分享平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

C语言 动态内存管理

C语言 动态内存管理引言C/C程序的内存开辟声明一、动态内存管理函数1. malloc 和 free使用示例2. calloc使用示例3. realloc使用示例4. 注意事项二、动态内存管理函数使用时的错误示范程序清单1程序清单2程序清单3程序清单4程序清单5程序清单6三、经典的内存笔试题程序清单1程序…

【可转债,股票】低频量化数据

目录历史文章股票明日涨停预测指数60日线偏离数据上证指数 MA60偏离度深证成指 MA60偏离度创业板指 MA60偏离度中小100 MA60偏离度上证50 MA60偏离度沪深300 MA60偏离度中证500 MA60偏离度中证1000 MA60偏离度科创50 MA60偏离度恒生科技 MA60偏离度恒生科技指数 MA60偏离度可转…

【强化学习论文合集 | 2018年合集】二. AAAI-2018 强化学习论文

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

Pytorch2.0发布了,向下兼容,加一句代码,性能翻番

概述 介绍PyTorch 2.0&#xff0c;我们迈向PyTorch下一代2系列发行版的第一步。在过去的几年里&#xff0c;我们进行了创新和迭代&#xff0c;从PyTorch 1.0到最近的1.13&#xff0c;并转移到新成立的PyTorch基金会&#xff0c;它是Linux基金会的一部分。 除了我们令人惊叹的…

Python中的全局变量与命名法

--------------------------------------------------------------------------------------------------------------------------------- 在本文章中&#xff0c;我们来讨论一下python中的全局变量&#xff0c;我们将学习如何定义全局变量&#xff0c;然后如何在函数中访问它…

HTML静态网页作业——澳门英文旅游网站设计与实现HTML+CSS+JavaScript

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…