返回顶部
首页 > 资讯 > 精选 >为JAVA性能而设计(三)
  • 253
分享到

为JAVA性能而设计(三)

2023-06-03 07:06:22 253人浏览 独家记忆
摘要

  第三部分: 远程接口  概述  许多 Java 的通常性能问题来源于设计过程早期的类设计想法中, 早在开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了一些通常的 Java 性能的冒险, 解释了怎样在设计时间避

  第三部分: 远程接口

  概述
  许多 Java 的通常性能问题来源于设计过程早期的类设计想法中, 早在开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了一些通常的 Java 性能的冒险, 解释了怎样在设计时间避免它们. 在这篇文章中, 它检验了远程应用程序中的特定的性能问题.

  远程调用的概念

  在分布式的应用程序中, 一个运行在一个系统中的对象可以调用另一个系统中的一个对象的方法. 这个通过很多使远程对象表现为本地的结构的帮助而实现. 要访问一个远程对象,你首先要找到它, 可以通过使用目录或者命名服务来实现, 象 RMI 注册, JNDI, 或者 CORBA命名服务.

  当你通过目录服务得到一个远程对象的引用时, 你并没有得到那个对象的实际的引用, 而是一个实现了和远程对象同样接口的stub对象的引用. 当你调用一个stub对象的方法时, 对象把方法的所有参数汇集起来 -- 把它们转化成一个字节流的表现形式, 类似于序列化过程. 这个stub对象把汇集的参数通过网络传递给一个skeleton对象, 把参数分解出来, 你想调用的实际的对象的方法. 然后这个方法向skeleton对象返回一个值, skeleton对象把它传送给stub对象, stub对象把它分解出来, 传递给调用者. Phew! 一个单独的调用要做这么多的工作. 很明显, 除去表面的相似性, 一个远程方法调用比本地方法调用更大.

  以上描述浏览了一些对于程序性能非常重要的细节. 当一个远程方法返回的不是一个原类? 而是一个对象时, 会发生什么? 不一定. 如果返回的对象是一种支持远程方法调用的类型, 它就创建一个中stub对象和一个skeleton对象, 在这种情况下需要在注册表中查找一个远潭韵,这显然是一个高代价的操作. (远程对象支持一种分布式的垃圾回收的形式, 包括了每一个参与的 JVM 维护一个线程来和其他 JVM 的维护线程进行通讯, 来回传递引用信息). 如果返回的对象不支持远程调用, 这个对象所有的域和引用的对象都要汇集起来, 这也是一个代价的操作.

  远程和本地方法调用的性能比较

  远程对象访问的性能特征和本地的不一样:远程对象的创建比本地对象创建代价要高. 不仅仅是当它不存在时要创建它, 而且stub对和skeleton对象也要创建, 还要互相感知.

  远程方法调用还包括网络的传递 -- 汇集起来的参数必须发送到远程系统, 而且响应也需汇集起来, 在调用程序重新得到控制权之前发送回来. 汇集, 分解, 网络延时, 实际的远调用所导致的延迟都加在一起; 客户端通常是等待所有这些而步骤完成. 一个远程调用也大地依赖于底层网络的延时.

  不同的数据类型有不同的汇集开支. 汇集原类型相对来说花费少一些; 汇集简单的对象, Point 或者 String 要多一些; 汇集远程对象要多得多, 而汇集那些引用非常多的对象的对象(象 collection 等)要更多. 这和本地调用完全矛盾, 因为传递一个简单对象的引用比一个复杂对象的引用花费多.

  接口设计是关键

  设计不好的远程接口可能完全消除一个程序的性能. 不幸的是, 对本地对象来说好的接口的特性对远程对象可能不适合. 大量的临时对象创建, 就象在本系列的第一, 二部分讨论,也能阻碍分布式的应用程序, 但是大量的传递更是一个性能问题. 所以, 调用一个在一个时对象(比如一个 Point)中返回多个值的方法比多次调用来分别得到它们可能更有效.

  实际远程应用程序的一些重要的性能指导:

  提防不必要的数据传递. 如果一个对象要同时得到几个相关的项, 如果可能的话, 在一个远程调用中实现可能容易一些.
  当调用者可能不必要保持一个远程对象的引用时, 提防返回远程的对象.当远程对象不需要一个对象的拷贝时, 提防传递复杂对象.
  幸运的是, 你可以通过简单查看远程对象的接口来找出所有的问题. 要求做任何高层动作的方法调用序列可以从类接口中明显看到. 如果你看到一个通常的高层操作需要许多连续的远程方法调用, 这就是一个警告信号, 可能你需要重新查看一下类接口.

  减少远程调用代价的技巧

  一个例子, 考虑下面假定的管理一个组织目录的应用程序: 一个远程的 Directory 对象包含了 DirectoryEntry 对象的引用, 表现了电话簿的入口.

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();
}

  现在假设你想在一个 GUI email 程序中使用 Directory 的东西. 程序首先调用getEntries() 来得到入口的列表, 接着在每个入口中调用 getName(), 计算结果的列表,当用户选择一个时, 应用程序在相应的入口调用 getEmailAdress() 来得到 email 地址.

  在你能够写一封 email 之前有多少远程方法调用必须发生? 你必须调用 getEntries() 一次, 地址簿中每个入口调用一次 getName(), 一次 getEmailAddress(). 所以如果在地址中有 N 个入口, 你必须进行 N + 2 次远程调用. 注意你也需要创建 N + 1 个远程对象引用, 也是一个代价很高的操作. 如果你的地址簿有许多入口的话, 不仅仅是打开 email 窗口的时候非常慢, 也造成了网络阻塞, 给你的目录服务程序造成高负载, 导致可扩展性的问题.

  现在考虑增强的 Directory 接口:

public interface Directory extends Remote {
String[] getNames();
DirectoryEntry[] getEntries();
DirectoryEntry getEntryByName(String name);
void addEntry(DirectoryEntry entry);
void removeEntry(DirectoryEntry entry);
}

  这将减少多少你的 email 程序所造成的花费呢? 现在你可以调用 Directory.getNames()一次就可以同时得到所有的名字, 只需要给你想要发送 email 的容器调用 getEntryByName() .这个过程需要 3 个远程方法调用, 而不是 N + 2, 和两个远程对象, 而不是 N + 1 个.如果地址簿有再多一点的名字, 这个调用的减少在程序的响应和网络负载和系统负载有很大的不同.

  用来减少远程调用和引用传递的代价的技术叫做使用次要对象标识符. 使用一个对象的标属性, -- 在这个例子中, 是 name -- 而不是传回一个远程对象, 作为对象的一个轻量级晔斗?次要标识符包含了它描述的对象足够的信息, 这样你只需要获取你实际需要的远程对象.在这个目录系统的例子中, 一个人的名字是一个好的次要标识符. 在另一个例子中, 一个安全皮包管理系统, 一个采购标识号可能是一个好的次要标识符.

  另一个减少远程调用数量的技巧是块获取. 你可以进一步给 Directory 接口加个方法, 来一次获取多个需要的 DirectoryEntry 对象:

public interface Directory extends Remote {
String[] getNames();
DirectoryEntry[] getEntries();
DirectoryEntry getEntryByName(String name);
DirectoryEntry[] getEntriesByName(String names[]);
void addEntry(DirectoryEntry entry);
void removeEntry(DirectoryEntry entry);
}

  现在你不仅可以得到需要的远程 DirectoryEntry , 也可以用单独一个远程方法调用得到要的所有的入口. 虽然这并不减少汇集的代价, 但极大地较少了网络往返的次数. 如果网延迟很重要的话, 就可以产生一个响应更快的系统(也能减少这个网络的使用).

  照亮去向 RMI 层次的路径的第三的技巧是不把 DirectoryEntry 作为一个远程对象, 而把它定义为一个通常的对象, 带有访问 name, address, email address 和其他域的访问函数.(在 CORBA 系统中, 我可能要使用类似的 object-by-value 机制.) 然后, 当 email 应用程序调用 getEntryName() 时, 它会获取一个 entry 对象的值 -- 不需要创建一个stub对象或者skeleton对象, getEmailAddress() 的调用也是一个本地的调用而不是一个远程的.

  当然, 所有这些技巧都都依赖于对远程对象实际上是怎样使用的理解上的, 但是对于这个理解, 你甚至不需要看一看远程类的实现就可以找出一些潜在的严重性能问题.

  结论

  分布式的应用程序的性能特性本质上和本地程序不同. 许多对于本地程序代价很小的操作对于远程应用程序来说代价非常高, 设计不好的远程接口导致一个程序有严重的扩展性和能问题.

  幸运的是, 很容易在设计时候, 为那些高代价的操作(象远程调用和远程对象创建), 通过平常的用例和分析它们, 确定和解决许多通常的分布式的性能问题, 正确使用这里提到的技巧,次要的对象标识符, 块获取和 return-by-value -- 可以本质上提高用户响应时间和整个统的吞吐量.

[@more@]

--结束END--

本文标题: 为JAVA性能而设计(三)

本文链接: https://lsjlt.com/news/233408.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 为JAVA性能而设计(三)
      第三部分: 远程接口  概述  许多 Java 的通常性能问题来源于设计过程早期的类设计想法中, 早在开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了一些通常的 Java 性能的冒险, 解释了怎样在设计时间避...
    99+
    2023-06-03
  • 为JAVA性能而设计(二)
      第二部分: 减少对象创建  概要  许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者开始考虑性能问题之前. 在这个系列中, Brian Goetz 讨论了通常的 Java 性能上的冒险以及怎么在设计...
    99+
    2023-06-03
  • 为JAVA性能而设计的示例分析
    这篇文章主要介绍为JAVA性能而设计的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!  第一部分: 接口事宜  概要  许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想, 早在许多开发者开...
    99+
    2023-06-03
  • JAVA性能设计方法是什么
    本篇内容介绍了“JAVA性能设计方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!  概要  许多通常的 Java 性能问题都起源于在...
    99+
    2023-06-03
  • Win7设置电源模式为高性能计划方法
    一般来说,咱们的win7系统电脑中电源计划都有平衡、节能、高性能,可能很多朋友都不知道,这三个性能并非只是摆设,而是有一定的存在必要的,因为对于用户来说,完全可以根据自己的用途来选择对应的电源计划,这样才能让咱们的电脑更...
    99+
    2023-06-13
    Win7 电源模式 高性能计划 计划 模式 高性能 电源
  • C++怎么为多线程性能设计数据结构
    本篇内容主要讲解“C++怎么为多线程性能设计数据结构”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++怎么为多线程性能设计数据结构”吧!8.3.1 为复杂操作划分数组元素假设你正在做一些复杂的...
    99+
    2023-06-16
  • Java中性能相关的设计模式有哪些
    这篇文章主要介绍“Java中性能相关的设计模式有哪些”,在日常操作中,相信很多人在Java中性能相关的设计模式有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中性能相关的设计模式有哪些”的疑惑有所...
    99+
    2023-07-02
  • 视野 | KeyDB:为 Web 应用而生的高性能 Redis 分支
    王奇 顾问软件工程师 目前从事 PaaS 中间件服务(Redis / MongoDB / ELK 等)开发工作,对 NoSQL 数据库有深入的研究以及丰富的二次开发经验,热衷对 NoSQL 数据库领域内的最新技术动态的学习,能够把握行业...
    99+
    2020-03-21
    视野 | KeyDB:为 Web 应用而生的高性能 Redis 分支
  • java为什么要设计异常?
    从业这么多年,每当谈起异常,都是懵懵懂懂,只是依稀记得它是处理错误的,当程序出错,日志里会有异常日志,可以查看异常定位错误。但是最近突然发现一个问题,那就是处理错误不一定非的要用异常啊,比如说参数合法性检查等等,判断是否为空后直接返回校验信...
    99+
    2019-06-27
    java教程 java 异常
  • 笔记本电脑怎么设置电源计划为高性能
    小编给大家分享一下笔记本电脑怎么设置电源计划为高性能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!右键点击桌面计算机,在打开的菜单项中选择属性;控制面板 - 所有...
    99+
    2023-06-27
  • 如何优化Java程序设计和编码提高性能
    这篇文章给大家介绍如何优化Java程序设计和编码提高性能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。通过使用一些辅助性工具来找到程序中的瓶颈,然后就可以对瓶颈部分的代码进行优化。一般有两种方案:即优化代码或更改设计方...
    99+
    2023-06-17
  • 软件工程(十七) 行为型设计模式(三)
    1、观察者模式 简要说明 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新 速记关键字 联动,广播消息 类图如下 基于上面的类图,我们来实现一个监听器。类图中的Subject对应我们的被...
    99+
    2023-08-30
    软件工程 设计模式
  • PHP中的高性能架构设计
    PHP语言作为一种开源的高级编程语言,已经成为了互联网应用开发的主流之一。与此同时,随着互联网应用的复杂性和流量的增大,越来越多的企业和开发者开始关注PHP性能的优化问题。在这篇文章中,我们将探讨PHP中的高性能架构设计。PHP的性能问题在...
    99+
    2023-05-23
    PHP 高性能 架构设计
  • java设计模式--三种工厂模式详解
    目录简单工厂代码:1.产品接口2.产品接口实现子类3.简单工厂类4.调用工厂5.测试工厂方法代码:1.工厂接口2.工厂实现子类3.产品接口4.产品实现子类5.调用6.测试1.产品接口...
    99+
    2024-04-02
  • 设计性能更优MySQL数据库schema
    目录数据类型优化选择优化的数据类型整数类型实数类型字符串类型日期和时间类型位数据类型mysql schema设计中的缺陷范式和反范式范式的优点和缺点反范式化的优点和缺点混用范式化和反范式化缓存表和汇总表物化视图计数器表加...
    99+
    2024-04-02
  • 怎么设计一个高性能网关
    这篇文章主要介绍“怎么设计一个高性能网关”,在日常操作中,相信很多人在怎么设计一个高性能网关问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么设计一个高性能网关”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-15
  • Web性能测试实例设计分析
    本篇内容介绍了“Web性能测试实例设计分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!首先,为什么要进行性能测试?性能不佳的应用通常无法实...
    99+
    2023-06-05
  • PHP设计模式:性能优化技巧
    在 php 中采用设计模式可以显著提升性能。单例模式可减少重复计算,工厂模式可优化对象创建,观察者模式能解耦组件,适配器模式可简化组件间通信,策略模式允许动态选择最佳算法,从而实现高性能...
    99+
    2024-05-13
    php 性能优化 并发访问
  • 利用高级Java、算法、三角学、分布计算设计自己的智能机器人 (转)
    利用高级Java、算法、三角学、分布计算设计自己的智能机器人 (转)[@more@]利用高级Java、算法、三角学、分布计算设计自己的智能机器人--(重锤痛击续2)http://www.ibm.com/developerworks/&nbs...
    99+
    2023-06-03
  • 数据库-表结构设计性能优化
    在进行数据库表结构设计时,最优性能设计建议如下: 客户端IP两种存储方式(不考虑ipv6): 1)、int 2)、 char(10) 性能上考虑推荐使用int。 有些表的电话号码 改成varchar(12),严格上...
    99+
    2018-02-21
    数据库-表结构设计性能优化 数据库入门 数据库基础教程 数据库 mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作