首页

文章

如何提高系统性能指标

发布网友 发布时间:2022-04-20 01:54

我来回答

1个回答

热心网友 时间:2023-08-05 02:01

前言当我写下这个标题后,我被自己吓啦一大跳,怎么取个这么大的题目。要知道这可是无数人一生的舞台!我在这里不想也不可能针对提高系统性能的方方面面一一讲解,只是想结合具体的个案来谈谈我们在进行系统移植过程中对提高 J2EE 系统性能指标的一些思考和设计方案,主要是关于数据缓存技术的应用,但愿不会给大家带来太大的误会。说明:本文所有的讨论都是基于 Windows 平台,至于其他主流平台比如 Unix、Linux 等也有类似于 MMF 的实现机制,在此不再赘述。回页首概念-- 什么是 MMF ? (1)从现在开始,MMF 一词将在本文中大量出现。所以,我在此先对 MMF 做一个简单的描述。MMF,全称 Memory Mapped Files,从宏观上看,它是一种数据内存映射的技术或者说管理动态内存的一种方法,Randy Kath 这样定义到 MMF:Memory-mapped files(MMFs) offer a unique memory management feature that allows applications to access files on disk in the same way they access dynamic memory-through pointers。从微观的角度,它主要具有以下几个特性:概念:MMF 是一个 Windows 对象,你可以通过 Windows API 创建和访问它。本质:你可以把 MMF 当成一个普通的文件,只不过它贮存在系统内存中。
图一:MMF 在各个进程间实现共享(来自 MSDN Online)特性:MMF 可以被任何进程、线程所访问,这说明 MMF 具有可在进程间共享的特性,这也正是它的最大"魅力"所在。当然,因为所有的存取操作都在内存中进行,它也同时具备快速的特点。实现原理:MMF 是基于现代操作系统都普遍采用的虚拟内存(virtual memory)技术,而虚拟内存是基于一种被称作 Paging 的机制之上的(2)。所以可以这样认为,只要某个操作系统采用了基于 Page 的虚拟内存管理系统,它就可以实现 MMF 这种功能特性。生存周期:MMF 一直存在直到对它的最后一个引用被断开。MMF 其实是 Windows 平台下的一个基本特性,所有关于它的操作都可以通过 Windows API 获得,它使得 DNA 架构下 COM 跨进程访问数据成为可能。利用它,可以将数据库端的业务数据缓存到应用服务器端或者客户端的 MMFs 中,省去频繁访问数据库的开销,极大地提高系统访问性能。对于 Java,我们也在 Jdk1.4 的 NIO 规范下找到了利用 MMF 的类集合,虽然在 Jdk1.4 的 API 文档中并没有明确地提出这样一个概念,但是我们在 FileChannel 和 ByteBuffer 类的文档中了解到 FileChannel 对象具有映射文件至内存的功能,从上面的介绍中我们可以看出这实际上就是创建了 MMF。回页首背景-- 我们遇到什么困难?我们希望对某个购买系统进行升级开发,自然就会涉及到平台的选型。原来的系统是基于微软的 DNA 架构,我们现在倾向于将之移植到 J2EE 平台。在此之前自然要进行必要的可行性分析,除去其他方面的考虑之外,我们最关心的自然落到关键技术的可行性上面,因为我们希望最大限度地利用原有系统的架构设计。由于该系统基于微软的 DNA 架构,采用 DCOM 远程访问组件的方式,系统性能自然成为一个非常重要的考虑。所以,在原有系统中最大的亮丽之处在于花费大量工作来提高整个系统的性能指标,使得整个系统无论在系统响应速度,还是大数据量并发操作方面都有很杰出的表现。在这其中尤以数据缓存技术 MMF 的应用最为关键,通过服务器端和客户端的数据缓存,有效地提升了整个系统的性能。图二:应用 MMF 后的系统图图示说明:图中的"Server Cache(Business Rules)"部分即为利用 MMF 进行的数据缓存;另外,在客户端也大量利用到 MMF,在图中并未标出。整个系统沿着这样一个思路来利用 MMF:每次系统启动的时候,程序访问数据库,获取表中数据,通过一系列步骤将之缓存至应用服务器端 MMFs,见下图中黑线所示。以后客户端每次请求数据,将直接访问应用服务器端 MMFs,见图中红线所示,并且同时将数据缓存到客户端。此后,如果有任何配置数据的改变,可以重新装载数据到 MMFs。当然,与之配套的还有一套比较合理的定时数据比较机制。图三、系统与 MMF 的交互图以上这些就是我们所要实现的 MMF 缓存机制,简单地说,我们就是要在 Java 中找出与之对应的缓存机制解决方案。回页首解决方案 -- 我们想到了什么?明确了目标之后,我们就开始了在 Java 中寻找的征程。可以说几乎涵盖了现有的所有可行的方案,下面就是我们探索和思考的点点滴滴。一、 利用 JNI我们首先想到的就是 JNI(Java Native Interface,Java 本地接口 ),毕竟这是最直观和最省事的解决方案。在 Java 中利用 JNI 直接调用已有的 VC 或者 VB 代码,不需要重新编写这些代码,节省了时间,而且程序执行效率也相当不错。但是,利用 JNI 也存在着诸多的问题:不同程序代码之间的兼容性和可协调性,不易维护性。总之,对于这种夹生饭可以作为一时的权宜之计,在项目时间紧迫的情况下可以考虑使用,但是从长远考虑还是不宜采用。(3)二、 利用 XML这其中我们也想到了利用 XML,作为时下非常流行和实用的一门技术,Jdk1.4 中提供了一整套比较完整的 XML API,使得产生以及解析 XML 文件变得非常的容易。但是,个人觉得 XML 最大的优势在于为不同系统间的数据交换提供一种通用的格式,在于数据存储、解析和转换方面,作为数据缓存的候选虽然也未尝不可,但是从最优系统性能和充分继承原有系统架构考虑,还不是最优解决方案。三、 利用 MMF因为原有系统是使用的 MMF,所以我们也自然而然想到了 JAVA 中是否也存在 MMF。经过对 Jdk1.4 的仔细研究,我们也如愿找到了我们希望的功能。经过各方面的讨论,我们决定在新系统中采用该技术。回页首解决方案 -- 我们做了些什么?在做出决定之后,我们就需要对 Java 中的 MMF 做一个详细的研究。在 Jdk1.4 中,关于 MMF 的 API 主要位于 java.nio 和 java.nio.channels 包下。在新的 JAVA NIO 中着重提到两个概念 Buffer 和 Channel,MMF 其实是作为它们的一个附属品被提出来的。其中的 FileChannel 类的 map 方法能够完成这样一种功能"Maps a region of this channel's file directly into memory",返回一个 MappedByteBuffer 对象。由此我们可见在 Jdk1.4 中,MMF 的表现形式为 MappedByteBuffer 类及其父类 ByteBuffer,你可以通过这些类提供的一些方法来操纵 MMF 对象,而创建 MMF 的功能主要由 FileChannel 类来完成。(4)在使用类 MappedByteBuffer 之前,你必须弄清楚这样几个概念:capacity, limit, position,这在所有 Buffer 类中都是非常关键的。这里我直接引用 Jdk1.4 文档中的解释:A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.A buffer's limit is the index of the first element that should not be read or written. A buffer's limit is never negative and is never greater than its capacity.A buffer's position is the index of the next element to be read or written. A buffer's position is never negative and is never greater than its limit.也许这样一个数学公式更加直观:0 <= position <= limit <= capacity。在进行大规模的系统应用之前,我们建立个简单的应用模型。今天,我们介绍一下这其中关于 MMF 最简单的一些操作。1、 创建 MMF上面我们已经提到,调用 FileChannel 类的 map() 方法可以创建 MMF,详细的方法说明如下: abstract MappedByteBuffer map(FileChannel.MapMode mode, long position, long size) 通过设置不同的 MapMode 类型,可以分别得到只读的、可读写的和私有的 MMF,因此可以视情况而定创建不同的 MMF。同时通过设置参数 position 和 size 可以指定文件的某一部分映射至内存,该特点对于大文件是非常有用的。 // 清单一:创建不同类型的 MMF try { File file = new File("filename"); // 创建一个只读的 memory-mapped file FileChannel roChannel = new RandomAccessFile(file, "r").getChannel(); ByteBuffer roBuf = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, (int)roChannel.size()); // 创建一个可读写的 memory-mapped file FileChannel rwChannel = new RandomAccessFile(file, "rw").getChannel(); ByteBuffer wrBuf = rwChannel.map(FileChannel.MapMode.READ_WRITE, 0, (int)rwChannel.size()); // 创建一个私有的 (copy-on-write) memory-mapped file. // Any write to this channel results in a private copy of the data. FileChannel pvChannel = new RandomAccessFile(file, "rw").getChannel(); ByteBuffer pvBuf = roChannel.map(FileChannel.MapMode.PRIVATE, 0, (int)rwChannel.size()); } catch (IOException e) {} 2、 向 MMF 中插入数据你可以利用类 MappedByteBuffer 的 capacity 来得到它里面包含的字节数,这是个常量。你可以利用方法 put() 来向 MMF 中插入数据,它有两种不同的版本:绝对位置插入 put(int index, byte b),为此你必须指定 index(0<=index<=capacity-1);相对位置插入 put(byte b),它是利用了 position 和 limit 属性。利用相对位置插入数值后,position 也相应地加 1,直至达到 limit 的*。而且,针对不同的数据类型,有各自相对应的 put 方法,比如 putChar, putDouble 之类。 // Create an empty MappedByteBuffer with a 10 byte capacity ByteBuffer bbuf = MappedByteBuffer.allocate(10); // Get the buffer's capacity int capacity = bbuf.capacity(); // 10 // Use the absolute put(). // This method does not affect the position. bbuf.put(1,(byte)0xFF); // position=0 // Set the position bbuf.position(5); // Use the relative put() bbuf.put((byte)0xFF); // Get the new position int pos = bbuf.position(); // 6 // Get remaining byte count int rem = bbuf.remaining(); // 4 // Set the limit bbuf.limit(7); // remaining=1 // This convenience method sets the position to 0 bbuf.rewind(); // remaining=7 3、 从 MMF 中获得数据与上述的过程相反,你可以通过不同的 get 方法来从 MMF 中获得数据。 // Create an empty MappedByteBuffer with a 10 byte capacity ByteBuffer bbuf = MappedByteBuffer.allocate(10); // Get the MappedByteBuffer's capacity int capacity = bbuf.capacity(); // 10 // Use the absolute get(). // This method does not affect the position. byte b = bbuf.get(5); // position=0 // Set the position bbuf.position(5); // Use the relative get() b = bbuf.get(); // Get the new position int pos = bbuf.position(); // 6 // Get remaining byte count int rem = bbuf.remaining(); // 4 // Set the limit bbuf.limit(7); // remaining=1 // This convenience method sets the position to 0 bbuf.rewind(); // remaining=7 回页首解决方案 -- 需要注意的地方上面我们给出的只是一个非常简单的读写 MMF 的例子,在实际的使用过程中会复杂得多,下面几个因素可能是你要好好考虑的:1、 数据与 MMF 的对应关系既然是要将数据缓存到 MMF 中,那我们就必须确立数据库表与 MMF 的对应关系。我们推荐使用的方式是每一张表对应一个 MMF 文件。2、 MMF 文件长度的设计确立了对应关系之后,我们需要分析一下如何设定 MMF 文件的初始长度。文件长度不能太小,否则就不能容纳所有的数据,同时文件也不能太长,那样一来浪费系统内存,二来也会使创建 MMF 的开销急剧增大。那刚好能容纳所有的记录呢?听起来是个不错的主意,但是如果这个时候需要添加一条记录呢?麻烦就来啦,由于原有长度不够。系统需要重新 re-map MMF 文件,造成系统内频繁地创建 MMF,反而使性能下降。经过我们研究后得出,这个比例在 1.1-1.3 之间比较合适,也就是 MMF 文件略大于表中现有记录的总和。3、 针对不同性质的数据进行不同的处理明确以上两点,我们还需要对数据本身做一番研究。有些数据趋于固化,一般不会有什么改变,比如国家、省份等,而有些数据则会经常变化,比如产品等,对于这两种不同类型的数据,你可以采取不同的处理方式,以达到最优的系统性能。回页首可能存在的问题 -- 我们需要预防些什么?1、 MMF 不是万能灵药千万不要以为有了 MMF,你就可以高枕无忧,可以轻轻松松搞定系统的缓存机制。事实远非如此,MMF 只不过是一把利刃,更重要的是你自己要仔细认真地设计好系统的缓存机制。要知道,解决交通堵塞问题的关键不是把路修得多么宽,而是要合理地规划整个交通路线。要知道在某些操作系统中,使用 MMF 的代价是非常昂贵的,失去好的规划,你可能会适得其反,系统反而会更加的拥挤不堪。况且,使用 MMF 还会带来很多的副作用。2、 性能与数据差错容忍度之间的平衡我们知道,随着数据缓存的大量使用,不可避免地会产生某种程度上的数据不一致,也就可能会产生某些数据差错。所以说,数据缓存使用的力度决定于系统客户对这些错误的容忍程度有多大。在某些非常关键的业务数据应用数据缓存技术时,必须格外地小心。3、 需要额外的 MMF 支持代码如上所述,为了最大限度地减少数据的不统一,我们必须提供一套非常合理和有效的数据同步机制,某种程度上甚至可以认为数据同步机制的好坏决定了数据缓存技术的成败。而这些是我们在使用 MMF 的过程中需要额外提供的代码。4、 MMF 与平台的相关性现在大部分编程语言中使用 MMF 的方法都是,提供相应的接口创建和操作 MMF 或者系统 API,而底层的具体 MMF 细节则由相应的操作系统去决定。这样每种操作系统中 MMF 不同的实现细节也在某种程度上影响着我们对 MMF 的使用。5、 使用 MMF 必须十分的小心既然MMF 是贮存在系统内存中,所以对于某些错误必须时刻警惕,比如"Array Out of Bound"等。要是您的系统没有很好地捕获这些错误,您的系统可能会彻底崩溃。每当你编写这些 MMF 代码的时候,你必须时刻牢记在心:我是在与系统内存打交道,这家伙可是娇贵的很。6、 由于 Jdkl1.4 的推出时间不长,基于 MMF 的现有应用几乎没有,所以没有真正能够在现实环境中检验 MMF 的使用情况,可能会存在一些不可预知的风险。回页首总结通过以上的介绍,相信大家对 MMF 在 Java 中的应用都有了一个初步的印象。实际上,提高应用系统的性能一直是所有应用系统开发人员追求的目标。除去本文谈到的缓存技术之外,在 J2EE 中,你还可以通过各种池技术的应用,EJB 组件的优化来提高系统性能(5)。但愿,本文能够给你带来这方面的一些启示。参考资料 关于MMF,微软 MSDN 站点 Randy Kath 的文章"Managing Memory-Mapped Files in Win32"不可不读。另外关于 MMF 的应用实例,可以参考 Zhefu Zhang 的文章"High Performance Solution Ini File Class with MMF"。关于这一点,可以参考文章"What are Memory Mapped Files?"。利用JNI 来访问 MMF 的实例可以参考 Stanley Wang 的文章"Using Memory Mapped Files and JNI to communicate between Java and C++ programs"。关于Java NIO 新功能的详细讲解,请参考 Jdk1.4 的 API 文档,而 Richard G. Baldwin 的在线教学文档也不可不读。关于这些技术的应用,可以参考 developerWorks Java 技术专区相关的文章。关于作者王和全,毕业于南昌大学。现主要在J2EE平台上从事广电行业运营系统的开发工作,擅长组件技术,多层架构下的编程。喜欢钻研新的技术,最近又迷上了Linux。除了写程序,平生最大的爱好就是旅游,梦想有一天能开着自己的宝马去郊游。您可以通过 wanghequan@shdv.com与我联系,我期待着朋友们的来信。 关闭[x]关于报告滥用的帮助报告滥用谢谢! 此内容已经标识给管理员注意。关闭[x]关于报告滥用的帮助报告滥用报告滥用提交失败。 请稍后重试。关闭[x]developerWorks:登录IBM ID:需要一个 IBM ID?忘记IBM ID?密码:忘记密码?更改您的密码 保持登录。单击提交则表示您同意developerWorks 的条款和条件。 使用条款 当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。所有提交的信息确保安全。关闭[x]请选择您的昵称:当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。昵称:(长度在 3 至 31 个字符之间)单击提交则表示您同意developerWorks 的条款和条件。 使用条款. 所有提交的信息确保安全。
八月中国最凉快的地方 八月份哪里最凉快,去哪旅游好?美丽的地方 乱字同韵字是什么意思 华硕笔记本电脑触摸板怎么开笔记本电脑触摸板怎么开启和关闭_百度知 ... 陕西职务侵占案立案准则 结婚后我的恋情维系了十年,怎么做到的? 玉米仁子饭产自哪里 中国期货交易所的交易品种有哪些? 历史要怎么读,有啥诀窍 高中历史诀窍 年终会活动策划方案 深度解析:第一财经回放,探索财经新风向 逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 变形金刚08动画的问题 变形金刚08动画日语版剧情介绍 高分!换显卡nvidia控制面板被我卸了,重新安装显卡驱动后没了nvidia控... 我的nvidia控制面板被卸载了 怎么找回啊 卸载后 这个画面看着很奇怪_百 ... 李卓彬工作简历 林少明工作简历 广东工业职业技术学院怎么样 郑德涛任职简历 唐新桂个人简历 土地入股的定义 ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 加强生态系统保护有哪些举措? 怎样加强数据系统用户的管理 华为手机怎样加强安全系统 iphone5加强系统内置闹钟功能 如何增强系统安全性 如何增强系统稳定性 为增强系统的稳定可靠性,计算机网络系统在设计上采... 采取什么措施加强信息系统安全管理 如何加强空调系统的安全管理? 如何加强windows系统安全防护? 怎样增强系统的兼容性 简述常用的加强linux系统安全的方法 如何提高电脑操作系统的安全等级 如何加强电力系统安全管理 xp怎么加强系统的处理速度? 怎样提高电脑系统 怎样加强系统安全 一个立一个羽当在一起念什么。“”立羽“” 立羽念什么? 玻璃的原材料是什么啊。我没看到什么矿啊什么的是... 如何加强计算机应用系统设备的管理与维护 如何加强计算机系统的内部控制与管理学院 CAD制图和平面设计有没有什么关系 家装装修流程是怎样的? 家庭装修流程分几步? 家庭装修的一般流程是? 家装的一般流程? 家庭宽带多少兆合适? 家里准备装修,顺道办理宽带,可是家用宽带多少兆... 办理宽带时选择多少兆的才够用? 安装家庭宽带多少兆合适呢?一般需要考虑哪些因素? 一般家庭宽带要用多少的? 家用宽带一般用多少兆的合适? 家庭装宽度多少兆的合适? 家里宽带多少兆合适? 家用宽带多少兆够用? 家庭安装宽带一般几兆的最合适 家里装宽带,多少M比较合适呢? 目前家家户户都离不开宽带,家用多少兆合适? 家庭宽带一般办理多少兆够用了?
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com