Java性能设计

Java 日志框架解析:设计模式、性能 在平常的系统开发中,日志起到了重要的作用,日志写得好对于线上问题追踪有着很大的帮助。一个好的日志框架,既要方便易用,也要有较好的性能,减少日志输出对系统内存、CPU 的影响。 研究一款开源项目,学到的不仅仅是这个项目本身,还会学到很多设计思想,可以利用到日常工作中。 阅读详情
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> 很多程序员在一开始并不注重性能的设计,只有当系统交付运行时,才 发现问题并且开始解决这一问题,但往往这只能挽救一点点。性能的管理应该一开始 就被整合到设计和开发当中去。 最普遍的问题就是临时对象大量经常的创建,这为性能埋下隐患。 性能的问题来自很多原因,最容易解决的可能是:你选择了不好的算法来进行计算,如 用冒泡法来排序巨量数据,或者你每次使用数据时都要反复计算一次,这应该使用Cache。 你能很容易的使用工具(如Borland的Optimizeit)或压力测试发现这些问题, 一旦发现,就能够立即被纠正,但是很多Java的性能问题隐藏得更深,难于修改源码就能纠正, 如程序组件的接口设计。 现在我们倡导面向对象的组件可复用设计,无疑这样设计的优点是巨大的, 但是也要注意到对性能的影响。 一个java性能设计原则是,避免不必要的对象创建,对象的创建是非常耗时的, 所以你要避免不必要的临时或过多的对象创建, String是程序中最主要创建的对象,因为String是不变的,如果String长度被修改 将导致String对象再次创建,所以对性能有所注意的一般人就是尽量回避使用String, 但是这几乎是不可能的。 接口参数设计 举例 MailBot: MailBot邮件系统的有一个Header数据,它是character buffer,需要对这个character buffer 进行分析比较,那么你要做一个类Matcher,在这个类中你将Header数据读入然后配比, 一个不好的做法是: public class BadRegExpMatcher {   public BadRegExpMatcher(String regExp);   /** Attempts to match the specified regular expression against the input     text, returning the matched text if possible or null if not   */   public String match(String inputText); } 这个BadRegExpMatche要求入口参数是String ,那么如果MailBot要调用他,必须自己做一个 character buffer到String的转换: BadRegExpMatcher dateMatcher = new BadRegExpMatcher(...); while (...) { ... //产生新的String String headerLine = new String(myBuffer, thisHeaderStart, thisHeaderEnd-thisHeaderStart); String result = dateMatcher.match(headerLine); if (result == null) { ... } } 很明显,这里这个由于接口不一致导致了多余的对象String headerline的创建,这是不能允许的, 应该将Matcher的接口设计成能够接纳character buffer,当然为通用性,也应该提供String的 接口参数: class BetterRegExpMatcher {   public BetterRegExpMatcher(...);   /** 提供多个接口参数的match方法   Provide matchers for multiple formats of input -- String,   character array,   and subset of character array. Return   -1 if no match was made; return offset of match start if   a match was made. */     public int match(String inputText);   public int match(char[] inputText);   public int match(char[] inputText, int offset, int length);   /** Get the next match against the input text, if any */   public int getNextMatch();   public int getMatchLength();   public String getMatchText(); } 很明显BetterRegExpMatcher的运行速度将比前面BadRegExpMatcher运行速度快。 因为在你已经写好代码的情况下,你比较难于更改一个类的接口参数,那就应该在写程序之前多 多考虑你这些接口参数的类型设定,最好有一个通盘的接口类型规定。 减少对象的创建 临时对象是那些有很短的生命周期,通常服务一些非十分有用的目标,程序员通常使用临时对象作为 数据混合包传送或者返回,为避免上述示例哪些转换接口对象的构造,你应该巧妙的避免创造这些临时 对象,以防止给你的程序留下性能的阴影。 上述示例说明性能问题在于String对象,但是String在对象创建中又是如此的普遍,String是不变的,一旦赋值,就不会变化,不少程序员 认为不变的东西总是会导致坏的性能,其实它并不是这么简单,实际上,性能好坏在于你如何使用这个东西。 对于经常需要变化的String,很明显使用Stringbuffer来代替。 举例: 看下面两种实现: public class Component {   ...   protected Rectangle myBounds;   public Rectangle getBounds() { return myBounds; } } 和 public class Component {   public Rectangle getBounds() {     return new Rectangle(myBounds.x, myBounds.y, myBounds.height,                       myBounds.width);   } } 当使用Component分别对应有如下两种: Rectangle r = component.getBounds(); ... r.height *= 2; 和 int x = component.getBounds().x; int y = component.getBounds().y; int h = component.getBounds().height; int w = component.getBounds().width; 第一种使用方式缺点,r.height的使用已经脱离component,容易引起沟通上的误解,因为 Rectangle变化必须涉及component内容重新刷新,万一其它程序员不知道这个规则,修改 r.height(乘2),将不会去刷新component, 第二中方式是个提高,迫使componenet和其部件跟随在一起。但是带来问题是:创建了 四个临时对象。 改进办法是,在第一种的基础上,在Commponent中增加 public int getX() { return myBounds.x; } public int getY() { return myBounds.y; } public int getHeight() { return myBounds.height; } public int getWidth() { return myBounds.width; } 这样调用变成: int x = component.getX(); int y = component.getY(); int h = component.getHeight(); int w = component.getWidth(); 两全其美了不是? 这就是减少创建对象技巧之一: 增加finer-grained辅助功能 第二种技巧是:Exploit mutability 上例还有一种实现方式: public Rectangle getBounds(Rectangle returnVal) {   returnVal.x = myBounds.x;   returnVal.y = myBounds.y;   returnVal.height = myBounds.height;   returnVal.width = myBounds.width;   return returnVal; } 多巧妙,把Rectangle作为参数传进来修改一下再送出去。 技巧3是 融合变和不变于一身。 总结上面一些例子,发现一个规律:临时对象产生是在这种情况下产生的: 不变的要转换成可变的。那么针对这个根本原因我们设计出各取所需的方案。 以下例说明: Point是不变的,我们继承它,定义一个可变的子类。 public class Point {   protected int x, y;   public Point(int x, int y) { this.x = x; this.y = y; }   public final int getX() { return x; }   public final int getY() { return y; } } public class MutablePoint extends Point {   public final void setX(int x) { this.x = x; }   public final void setY(int y) { this.y = y; } } 这样,可变的需求和不可变的需求各自满足,分别调用。 public class Shape {   private MutablePoint myLocation;   //返回可变的   public Shape(int x, int y) {     myLocation = new MutablePoint(x, y);   }   //返回不变的   public Point getLocation() { return (Point) myLocation; } } 远程接口 在分布式应用中,性能也是相当重要的,这里介绍如何通过检查class的接口 能简单预知分布式应用中的性能问题。 在分布式应用中,一个在这个系统中运行的对象能够调用另外一个系统的对象的方法,这是通过很多 内部机制来实现将远程对象貌似本地对象的,为了发现远程对象,你首先必须发现它,这是通过一种 名称目录服务机制,比如RMO的注册,JNDO和CORBA的名称服务。 当你通过目录服务得到一个远程的对象,你不是得到一个实际的指向,而是一个和远程行为一样的stub对象的 指向, 当你调用stub对象的一个方法时,这个得marshal这个方法参数:也就是转换成byte-stream,这类似 于序列化,这个stub对象通过网络将marshal后的参数发送给skeleton对象,后者负责unmarshal这些参数然后 调用真正实际的你要调用的远程方法,然后,这个方法返回一个值给skeleton,再逐个沿着刚才路线返回, 一个简单方法要做这么多工作啊。 很显然,远程方法调用要比本地方法调用来得耗时昂贵。 上面返回情况是是指返回原始型primitive,如果返回的是对象,怎么办?如果这个对象支持 远程调用,它又会通过查询创造一个stub和skeleton对象,这又是耗时的;如果这个对象 不支持远程调用,那么所有的对象的字段和任何涉及引用的对象都要被marshal,这也是 相当耗时的。 由此可见,一个不好的远程接口设计将完全扼杀程序的性能,为了避免网络开销,设计一次 远程调用返回多值总比多次调用,每次只返回一个值要好得多。 还有提防在不需要返回远程对象时,返回一个远程对象。不要传递很复杂不必要的对象给远程。 假设远程服务器有一个目录列表对象,每个目录项目中包含姓名 电话号码 和邮件地址等值, 下列程序: public interface Directory extends Remote {   DirectoryEntry[] getEntries();   void addEntry(DirectoryEntry entry);   void removeEntry(DirectoryEntry entry); } public interface DirectoryEntry extends Remote {   String getName();   String getPhoneNumber();   String getEmailAddress(); } 这样设计导致结果是,当我需要一个姓名值时,首先要获得Directory 对象,再获得DirectoryEntry, 获得DirectoryEntry才能获得getName,这么来来回回,需要多少次网络开销啊。 public interface Directory extends Remote {   String[] getNames();   DirectoryEntry[] getEntries();   //加入这个方法   DirectoryEntry getEntryByName(String name);   void addEntry(DirectoryEntry entry);   void removeEntry(DirectoryEntry entry); } 这样直接在Directory加上DirectoryEntry和getNames(),一次网络开销就全部解决。 当然这样的解决方案是完全建立在对分布式应用原理了解的基础上。 本篇翻译(属于主要思想的翻译,非完全翻译)自 Brian Goetz 的Design for performance http://www.javaworld.com/javaworld/jw-01-2001/jw-0112-performance.html
Java高性能系统常见设计与优化 立即下载

相关推荐

Java 高性能系统常见设计与优化

Java 高性能系统常见设计与优化 Java 高性能系统常见设计与优化

(转)为Java性能而设计(1)

为性能而设计(1) 第一部分: 接口事宜 From Java World. 在设计 Java 类的时候避免性能上的冒险概要许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了通常的 Java 性能上的冒险以及怎么在设计时候避免它们. By Brian Goetz 翻译

heartsky189的专栏 718

管道机器人手臂机械结构设计cad【8张】+三维图+设计说明书+绛重

履带式管道机器人适用于各种管道环境,包括直管道、弯曲管道、水平管道、垂直管道等,其灵活性和适应性使得它可以应对不同形状和尺寸的管道,完成全面的检测和维护工作。管道机器人研究具有重要的现实意义和深远的社会影响,通过提高工作效率、降低人员风险、提升服务质量、节约成本资源和促进科技创新等方面的作用,为现代工程技术领域的发展和进步做出了积极的贡献。管道机器人是一种能够在管道内部执行各种任务的智能机器人,而管道机器人的机械臂对于管道机器人在管道内执行任务的灵活性、稳定性和效率至关重要。

kejigongjiang的博客 944

为JAVA性能而设计(二)

  翻译 by SuperMMX  阅读整个的 "为性能而设计" 系列:  第一部分: 接口事宜  第二部分: 减少对象创建  第三部分: 远程接口 (March 23, 2001)  第二部分: 减少对象创建  概要  许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了通常的 Java 性能

...... 699

DC-DC 转换器中的压电谐振器:当前状态和限制

在功率转换器应用中,居里温度较低的谐振器的 k 2和 Q M显着降低会导致效率降低,需要仔细的热处理。由于使用 PR 的功率转换器在不同的条件下运行,包括温度范围、电压偏置和功率电平,因此不可避免地会出现非线性效应,必须妥善解决这一问题,以免影响转换器的性能。等效电路模型(Butterworth Van-Dyke 或 BVD 模型)将压电谐振器在其机械谐振附近的电响应转换为一个简单电路,该电路由与由电极形成的输入电容 C 0并联的串联 RLC 动分支组成,见图图 1 还显示了阻抗与频率的关系。

2301_79716471的博客 1299

cosmos-curate工业级视频数据预处理引擎/终端用户指南( end-user-guide)

摘要:Cosmos-Curate是一个用于视频和自动驾驶数据处理的开源工具,提供从本地到集群的完整部署方案。文档针对三类用户:终端用户(配置运行现有管道)、开发者(修改/创建管道)和贡献者(改进代码库)。核心功能包括容器化设计(Docker+NVIDIA工具链)、多平台支持(本地/Slurm/云)、集成HuggingFace/NGC模型,以及可扩展的管道架构。使用需满足硬件(如Ampere架构GPU)和软件(Ubuntu22.04+Python3.10)要求,通过CLI工具构建镜像、下载模型并运行示例管道(

qq_45053161的博客 1204

为JAVA性能而设计(转)

出处:JavaWorld作者:Brian Go… 翻译 by SuperMMX  阅读整个的 "为性能而设计" 系列:  第一部分: 接口事宜  第二部分: 减少对象创建  第三部分: 远程接口 (March 23, 2001)...

150

芯片详解——AD7606

AD7606详解

weixin_45661757的博客 5022

Java性能与设计

很多程序员在一开始并不注重性能的设计,只有当系统交付运行时,才 发现问题并且开始解决这一问题,但往往这只能挽救一点点。性能的管理应该一开始 就被整合到设计和开发当中去。 最普遍的问题就是临时对象大量经常的创建,这为性能埋下隐患。 性能的问题来自很多原因,最容易解决的可能是:你选择了不好的算法来进行计算,如 用冒泡法来排序巨量数据,或者你每次使用数据时都要反复计算一次,这应该使用Cache。

leagle 831

ETAS工具导入Com Arxml修改步骤

通讯协议栈开发一般通过导入DBC实现,ETAS工具本身导入DBC也是生成arxml后执行cfggen,本文介绍直接导入客户提供的arxml文件,实现通讯协议栈的生成。通过Arxml导入相比于DBC来说,少了从DBC转为arxml的过程。而且arxml中能提供的信息也会更多。如果是DBC的话,很多信息(如PNC的映射,CANTP的配置等)都需要额外配置。不过还有连DBC都无法提供的,那就更麻烦了~

赞的博客 1542

STM32cubemx配置驱动DHT11模块

本篇文章将带大家学习使用DHT11湿温度模块,使用这个模块可以获取当前的温度和湿度数据。DHT11可以用于智能家居,蔬菜大棚等项目当中适用范围广。DHT11 是一种数字式温湿度传感器,由杜邦公司推出。它可以测量环境中的温度和湿度,并将测量结果以数字形式传输给微控制器或其他电子设备,适用于通过数字信号读取环境温湿度的应用场景。DHT11 传感器使用单总线数据交换协议,可以通过一个 I/O 引脚进行控制和数据传输。

m0_49476241的博客 5912

为JAVA性能而设计(一)

  翻译 by SuperMMX  阅读整个的 "为性能而设计" 系列:  第一部分: 接口事宜  第二部分: 减少对象创建  第三部分: 远程接口 (March 23, 2001)  第一部分: 接口事宜  概要  许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz讨论了通常的 Java性能上的冒险

...... 779

导航系统 | 全球四大卫星导航系统(2025)核心能力对比分析

北斗系统通过GEO卫星(80°E、110.5°E、140°E)实现区域增强,其IGSO卫星在亚太地区形成"8"字形轨迹,使该区域可见卫星数量比GPS多4-6颗,显著提升复杂环境下的定位可用性[13]。北斗短报文功能在2025年云南地震救援中发挥关键作用,被困人员通过北斗终端发送120字求救信息,实现"位置+状态"一体化上报,救援响应时间缩短40%[15]。北斗通过三频信号(B1C/B2a/B3)消除电离层延迟误差,在城市峡谷环境下定位连续性达99.98%,优于GPS的99.95%[5]。

尘世冰封的专栏 2615

提高java程序性能设计

 翻译 by SuperMMX  阅读整个的 "为性能而设计" 系列:  第一部分: 接口事宜  第二部分: 减少对象创建  第三部分: 远程接口 (March 23, 2001)  第一部分: 接口事宜  概要  许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz讨论了通常的 Java性能上的冒险以

guishuanglin的专栏 635

YOLOv11改进 | Neck篇 | 双向特征金字塔网络BiFPN助力YOLOv11有效涨点

本文给大家带来的改进机制是BiFPN双向特征金字塔网络,其是一种特征融合层的结构,也就是我们本文改进YOLOv11模型中的Neck部分,它的主要思想是通过多层级的特征金字塔和双向信息传递来提高精度。本文给大家带来的结构可以让大家自行调节网络结构大小,同时能够达到一定的轻量化效果,为什么发BiFPN呢因为它算是YOLO系列改进中的常青树了,大家可以借鉴它的双向特征思想来创新自己的Neck结构本文的BiFPN通过yaml文件配置可以让大家自行调配其结构。

Snu77的博客 9105

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Java设计模式性能优化:高效代码设计实战指南

还在为Java应用性能瓶颈而烦恼?本文深入解析三大核心性能优化设计模式,助你构建高性能Java应用系统! ## 性能优化的核心挑战 在现代Java应用开发中,性能优化面临三大核心挑战: 1. **内存管理效率低下** - 大量对象创建销毁导致GC压力 2. **资源竞争激烈** - 数据库连接、线程等资源争夺 3. **数据访问延迟** - 频繁的IO操作拖慢响应速度 通过合理运用设计模式...

gitblog_01194的博客 802

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

为JAVA性能而设计(1)

  为性能而设计, 第一部分: 接口事宜  From Java World.  [b]在设计 Java 类的时候避免性能上的冒险[/b]  [b][u]概要[/u][/b]  许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者  开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了通常的 Java 性能上的冒险  以及怎么在设计时候避免它们.  By Brian Goetz  翻译 by SuperMMX  许多程序员在开发周期的后期才可是考虑性能管理.

android专栏 679

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

3种JAVA程序设计性能优化

3种JAVA程序设计性能优化3种JAVA程序设计性能优化

冲浪口 187

Java编程精要从高效代码设计到实战性能优化之道

1. 最小化时间复杂度:优先选择时间复杂度更低的算法,如使用二分查找(O(logN))而非线性搜索(O(N))。- 减少对象创建:用 `StringBuilder` 替代字符串拼接,避免频繁生成短生存期对象。if (list.get(i).isValid()) ... // 每次取值且重复判断。// 时间爆炸,O(2^N)} // 关闭由JVM自动管理,无需手动调用close()

MmvlaFos的博客 550
上一篇: 快速开发时可以使用的Java文件工具方法
下一篇: 北京炎黄盈动诚聘英才
java169
博客等级 码龄19年 27粉丝 2568原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值