开发高性能JAVA应用程序基础(内存篇)

虽然JAVA的垃圾回收和当前高配置的服务器可以让程序员大部分时间忘掉OutOfMemoryError的存在,但是访问量增大后频繁的GC会额外消耗CPU (使用top查看结果为us值高),系统响应速度下降,积压的请求又会占用更多内存从而恶性循环,严重时可能导致系统不断Full GC造成应用停顿。

优化内存的使用可从以下几方面着手:

一、节流
1 使用单例模式

单例模式是开发者最早接触并使用的设计模式之一,尽管写代码的时候可能还不知道用了设计模式。简单来说就是构造函数private化,通过静态方法获得唯一实例。因为其特性,对于某些场景例如每次请求都要使用无状态工具类的检验方法,使用单例模式可以大量节省创建新对象的开销。

public class Singleton {private Singleton() {}private static Singleton instance = new Singleton();public static Singleton getInstance() {return instance;}public void doSomething() { }
}
2 缓存常用对象

简单来说就是按一定特征创建"对象缓存池",使用集合类保存已创建的对象,当有相同特征的对象申请时,使用缓存池中现有的对象代替通过 new关键字重新创建。

public class BigObjectPoolTest {public static void main(String[] args) {long start = System.nanoTime();for(int i = 0; i < 10000; i++) {BigObjectPool.getBigObject("xxx", true);}System.out.println("使用缓存池耗时" + TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS) + "毫秒");start = System.nanoTime();for(int i = 0; i < 10000; i++) {BigObjectPool.getBigObject("xxx", false);}System.out.println("不使用缓存池耗时" + TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS) + "毫秒");}
}class BigObjectPool {private static Map<String, BigObject> map = new HashMap<String, BigObject>();static {map.put("xxx", new BigObject("xxx"));map.put("yyy", new BigObject("yyy"));}public static BigObject getBigObject(String key, boolean usePool) {if(usePool) {BigObject bo = map.get(key);if(bo == null) {bo = new BigObject(key);}return bo;} else {return new BigObject(key);}}
}class BigObject{private String name;private byte[] data = new byte[1024 * 1024];public BigObject(String name) { this.name = name; }
}

以-Xms32m -Xmx32m -Xloggc:d:/gc.log 参数运行

使用缓存池耗时3毫秒
不使用缓存池耗时998毫秒
(查看gc.log,可以观察到不使用缓存池触发Minor GC 1000次以上)

实际业务中通常使用EhCache等框架代替自己实现缓存池。

与这种实现原理相似的也有一个设计模式:享元模式,区别是享元模式更关注类设计结构上的优化,对上下文环境的设计也做了明确定义。

3 避免设计过大的对象

如果业务模型中要求的类的属性和方法都非常多,可以尝试将其拆分成多个小类,再通过合成/聚合模式组装成一个大类,这也符合设计模式的优化思想。甚至可以结合上面的对象缓存池的方式将其中一部分内容缓存化。

class Composition {private BigObject bigObject = null;private int id;public void setBigObject(BigObject bigObject) {this.bigObject = bigObject;}public Composition(int id) {this.id = id;}
}

Composition c = new Composition(1);
c.setBigObject(BigObjectPool.getBigObject("xxx", true));
4 一些小技巧

使用StringBuilder代替用+号连接字符串

尽量使用int, long等基本类型代替Integer, Long包装对象

合理利用SoftReference和WeakReference

二、开源 - 调整虚拟机参数

一般设置 java -server -Xms2048m -Xmx2048m -XX:PermSize=256m  -XX:MaxPermSize=256m

-Xms和-Xmx决定java堆区可使用的内存最小值和最大值,通常设为相同的值,避免运行期间反复的重新申请内存。如果出现OutOfMemoryError: Java heap space,则在硬件允许的情况下临时调大-Xmx,为排查问题和优化代码争取时间。

-XX:PermSize和-XX:MaxPermSize决定永久代可用空间大小,存放class和meta信息,通常设置为相同的值。如果出现OutOfMemoryError: PermGen space,说明加载的类和jar文件过多,可以调大这两个参数值。

如果web容器下有多个应用引用了相同的第三方jar文件,可以转移到容器的共享目录。

另一个重要参数是-Xmn,决定堆区新生代的大小,通常占-Xmx的比值设置为1/4到1/3。如果业务中有大量体积大且生命周期很短的对象创建需求,可适当调大新生代空间以利于失效对象在新生代中被回收。

此外,可通过参数设置回收算法:

–XX:+UseSerialGC
–XX:+UseParallelGC
–XX:+UseParallelOldGC
–XX:+UseConcMarkSweepGC

回收算法的选择和对比需要较大的篇幅介绍,这里不做详细的解释。通常来说,对于响应时间优先的web应用,ConcMarkSweepGC(CMS)是个不错的选择。

需要注意的是,经过几代发展后,JVM对内存管理已经做的非常好。如果不是有明确的证据证明JVM的默认选择不合理,就没必要做过多细节的调整设置。调整后,可通过-XX:+PrintGCDetails -XX:+PrintGCTimeStamps等参数输出GC信息进行比对,优化的首要目标是减少Full GC次数和时间。


参考资料: 分布式java应用基础与实践

转载于:https://www.cnblogs.com/autfish/p/5557582.html

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

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

相关文章

【前端面试题】2021/3/12挺经典的面试题,这个经历很深刻。

今天面试去啦&#xff0c;填了职业性格测试&#xff0c;人格测试及招聘的基本经历信息&#xff0c;面试官是技术头头&#xff0c;柔中带钢&#xff0c;问题润物细无声的感觉&#xff0c;很考验基本功。 上午10:30面试了一个达达的前端&#xff0c;采用的是线上腾讯会议的方式&a…

html5 ios cookie,ios – WKWebView,获取所有cookie

我想从WKWebView获取所有cookie.为什么&#xff1f;我已经启动了一个使用基于Web的身份验证的项目.因此,我应该拦截cookie以确保用户已登录并用于其他目的.另一种情况 – 想象一下,如果用户登录,而不是“杀死”应用程序 – 由于存储此cookie会话的一些延迟将丢失:(.The problem…

【前端面试题】2021/3/15面试题

最近在boss直聘上投了很多简历&#xff0c;记录一下今天的面试题&#xff0c;这个好几个都是电话直接打过来问时间方便&#xff1f;我一回答方便就直接开始丢题目&#xff0c;我也不知道哪个公司的。感觉公司不是很正规的感觉&#xff0c;感觉那边有个问题题库&#xff0c;面试…

计算机考研数学基础知识点,2019计算机考研数学复习:打好基础是必须的啊喂!...

"基础不牢&#xff0c;地动山摇"这句话形容考研数学的复习真是太贴切不过了&#xff0c;尤其是对处于打基础阶段的19考研党们来说&#xff0c;新东方在线整理了2019计算机考研数学复习&#xff1a;打好基础是必须的啊喂!很多同学都存在着这样的误区&#xff1a;考研数…

javafx打包路径问题_关于JavaFX的最常见问题

javafx打包路径问题上周&#xff0c;我在斯德哥尔摩的Jfokus 2012上做了一个关于JavaFX的演讲&#xff0c;当时我意识到每次活动都会问三个问题。 似乎有一个普遍的兴趣&#xff0c;所以我尝试在这篇文章中回答他们&#xff08;尽可能的说实话&#xff09;&#xff1a; iPad或其…

【前端面试题】关于一些js的一些面试题(金融行业),我和面试官扯了三个小时

今天去面试了一家金融公司&#xff0c;招聘比较着急&#xff0c;一面后直接二面等结果&#xff0c;这种公司一般对js要求比较高&#xff0c;笔试题基本都是js相关的题&#xff0c;针对公司的客户要求也会做一些jquery,vue.react相关的插件&#xff0c;H5及webAPP。下面直接说题…

操作系统下查看HBA卡信息wwn的方法

一、Windows 系统在Windows系统中&#xff0c;可以使用FC HBA卡厂家提供的管理软件查看光纤适配器的WWN号码&#xff0c;具体如下&#xff1a;Qlogic&#xff1a;SANsurferEmulex&#xff1a;HBAnywarehttp://www.microsoft.com/en-us/download/details.aspx?id17530安装以后使…

上海大学计算机学院客座教授,刘云虹教授受聘上海大学外国语学院客座教授并做学术讲座...

11月29日14:00&#xff0c;南京大学外国语学院副院长、博士生导师刘云虹教授被我院聘为客座教授并做主题为《中国文学外译与翻译历史观》的学术讲座。学院副院长苗福光教授主持&#xff0c;副院长邓志勇教授(主持工作)为刘教授颁发了聘书。讲座从刘教授自己的学术研究领域和起点…

使用RxJava和SseEmitter进行服务器发送的事件

Spring Framework 4.2 GA即将发布&#xff0c;让我们看一下它提供的一些新功能。 引起我注意的一个事件是一个简单的新类SseEmitter &#xff0c;它是对Spring MVC控制器中易于使用的发送事件的抽象。 SSE是一项技术&#xff0c;使您可以在一个HTTP连接内沿一个方向将数据从服务…

常用正则表达式整理【总结】

平时不太喜欢记忆这些东西,开发的时候需要拿过来直接用就好,还有面试的时候直接让你敲的,这里记录一下。 目录 一、校验数字的表达式 二、校验字符的表达式

cmstop中实例化controller_admin_content类传递$this,其构造方法中接收到的是--名为cmstop的参数--包含cmstop中所有属性...

主程序cmstop类,实例化controller_admin_content类(接收请求后拼接的).传递cmstop所有属性过去.controller_admin_content.构造方法中接收到名称为cmstop,已经内容为cmstop所有属性 class cmstop extends object{public $app, $controller, $action, $args, $class } 设置好属性…

XPS 15 9530使用Windows10频繁发生Intel HD Graphics 4600驱动奔溃的一种解决方法

本人使用XPS 15 9530、集成显卡为Intel HD Graphics 4600、操作系统Windows 10 Pro&#xff0c;使用过程当中经常会发生集成显卡奔溃的问题&#xff0c;错误提示如下&#xff1a; Display driver stopped responding and has recovered Display driver Intel HD Graphics Drive…

安徽阜阳计算机高中学校排名,安徽阜阳排名靠前的三大高中,有争议?2020年高考成绩说话!...

安徽省阜阳市&#xff0c;古称汝阴&#xff0c;阜阳历史悠久、文化璀璨、人才辈出&#xff0c;有阜阳剪纸等国家非物质文化遗产&#xff0c;也是管仲、鲍叔牙等历史名人的故乡&#xff1b;阜阳风景秀丽&#xff0c;辖区内有诸多知名景点&#xff0c;其中八里河风景区为国家AAAA…

WAF安恒

http://wenku.baidu.com/view/c242927f581b6bd97e19ea1a.html?fromsearch转载于:https://www.cnblogs.com/diyunpeng/p/5317630.html

java se和java_Java:改进了Java SE 6和Java SE 7的客户端和桌面部分!

java se和javaJava 6和Java 7中的客户端改进 了解有关Java SE 6和Java SE 7的客户端和桌面部分的改进&#xff0c;包括新的applet插件&#xff0c;Java Deployment Toolkit&#xff0c;成形和半透明的窗口&#xff0c;重量级-轻量级混合以及Java Web Start。 介绍 自2006年12月…

【vue系列】小白入门篇,一天就能掌握vue开发技巧及规则

摘要:简单做了一个简单的vue入门,了解最基础的知识点,环境的配置,创建脚手架项目,创建uni-app项目。 vue官网文档:https://cn.vuejs.org/ uni-app官网文档:https://uniapp.dcloud.io/ HBuilderX:https://www.dcloud.io/hbuilderx.html 文章中涉及的代码下载 vue:https:/…

液位单闭环实验计算机控制,过程控制实验指导书

内容简介&#xff1a;过程控制实验指导书目 录第一章 前言............... ..........................................3第二章 过程控制仪表实验1&#xff0e; 压力、液位变送器的认识和校验.....................................52&#xff0e;调节器的认识和校验&#xff…

数组练习2

结对开发&#xff1a;张哲 张晓菲 题目&#xff1a;返回一个数组中子数组最大和&#xff0c;数组可以首尾相连。 一、实验思路 本次实验在第一次的基础上增加了一些难度&#xff0c;数组可以首尾相连组成一个环&#xff0c;我们两个经过思考和讨论后得到一个方法&#xff1a; …

Java 8中最快的垃圾收集器是什么?

OpenJDK 8具有几种垃圾收集器算法&#xff0c;例如Parallel GC &#xff0c; CMS和G1 。 哪一个最快&#xff1f; 如果默认的GC从Java 8中的并行GC更改为Java 9中的G1&#xff08;当前建议&#xff09;&#xff0c;将会发生什么&#xff1f; 让我们对其进行基准测试。 基准方法…