Java性能权威指南-总结22

news2024/9/26 5:24:08

Java性能权威指南-总结22

    • 对象序列化
      • 追踪对象复制
    • Java EE网络API
    • 小结

对象序列化

追踪对象复制

先介绍一个示例,如何不对对象引用进行序列化,以避免在反序列化时处理对象引用。然而,writeobject()中最有力的优化是不重复输出对象引用。StockPriceHistoryImpl中,这意味着不重复输出prices map。因为示例采用标准JDK中的mapJDK的类已经对数据的序列化进行了优化,所以不用担心。不过,了解这些类如何进行优化、理解哪些可能的优化都是有益处的。

StockPriceHistoryImpl中的关键结构是TreeMap。下图是一个简化版本的mapJVM默认先序列化Node A的原生数据字段,然后递归调用Node Bwriteobject()(接着是Node C)。Node B也会序列化它自己的原生数据字段,然后递归序列化它上级Node的字段。

但是请注意——Node B上级节点Node A已经被序列化,怎么办?对象序列化的代码很智能:它会意识到这一点,并且不会再次序列化Node A的数据。相反,它只会在先前序列化的数据中添加一个对象引用。追踪上一级对象从而递归所有对象,会对序列化的性能有少许影响。 但正如Point数组的例子所示,这是无法避免的:必须追踪上一级序列化的对象以便正确恢复对象引用。不过,可以通过压缩对象引用来进行智能优化,从而在对象反序列化时易于重建。在这里插入图片描述
不同的集类处理这个问题的方式有所不同。比如TreeMap,它只是遍历树然后序列化键值,丢弃了键之间的所有关系(也就是它们的排列顺序)。在反序列化时,readobject()会重新排列数据并生成树。虽然排序对象听起来代价很昂贵,但实际并非如此:对10000只股票而言,整个过程要比默认的序列化快20%,默认机制需要追踪所有的对象引用。

需要序列化的对象减少了,因此TreeMap也能从优化中获益。map中的Node(在JDK中为Entry)包含两个对象:键和值。由于map不会包含两个相同的Node,所以序列化保留Node的对象引用时不用担心。在这种情况下,它不会序列化Node对象本身,而是直接序列化键和值。所以最终的writeObject()看起来像这样(为便于阅读,代码作了调整):

	private void writeobject(ObjectoutputStream oos) throws IOException {
		for (Map.Entry<K,V>e : entrySet()) {
			oos.writeobject(e.getKey());
			oos.writeObject(e.getValue());
		}
	}

这段代码看起来与Point示例中的那段不能正常工作的代码非常像。差别在于该段代码会序列化相同的对象。TreeMap不会有两个相同的Node,所以没有必要序列化Node引用。TreeMap可以有相同的值,所以值必须序列化成对象引用。这就回到了起点:正确优化对象序列化非常困难。但当对象序列化成为应用的主要瓶颈时,恰当地进行优化可以带来很大的益处。

关于Externalizable接口
这两个接口的差别在于它们如何处理非transient字段。当writeObject()调用defaultMriteObject()时,Serializable会序列化非transient字段。但Externa-lizable没有这样的方法。
Externalizable类必须显式序列化所有关注的字段,无论transient与否。
即便一个对象中的所有字段都是transient,也最好实现Serializable接口,并调用defaultMriteObject()方法。这使得代码在添加(移除)字段时更容易维护。从性能的角度来看,
Externalizable并没有特别的优点:最终影响性能的是数据量的大小。

快速小结

  1. 数据的序列化,特别是Java EE中的序列化,有可能是很大的性能瓶颈。
  2. 将变量标记为transient可以加快序列化,并减少传输的数据量。这些做法都可以极大地提高性能,除非接收方重建数据需要花费很长时间。
  3. 其他writeobject()readobject()方法的优化也可以显著加快序列化。但这容易出错,而且不留神就会引入不易察觉的bug。
  4. 通常在序列化时进行压缩都有益处,即便数据不在慢速网络上传输。

Java EE网络API

前面介绍过的几种数据交换技术——XML解析、JSON处理和对象序列化——可以在不同的应用中使用,但主要是在JAX-WS、JAX-RS和ⅡOP/RMI这三个Java EE网络API中使用。

这些API的协议差别很大,特性也有很大的不同。在决定为何使用它们以及何时使用它们时,考虑的首要因素就是它们的特性。关于它们有许多争论,比如JAX-RS是否比JAX-WS快,不过这些争论都假设有这样一个通用型应用,这个应用可以用两种框架编写。如果确定需要安全特性,那就应该选择JAX-WS,而不管它与JAX-RS相比性能如何。如果应用必须和已有的输出ⅡOP接口的服务器通信,那么选择也就显而易见了。但对于这几种网络API来说,它们需要克服的性能问题类似。这部分将讨论其中的一些困难以及如何处理这些困难。

调整传输数据的大小
影响这些技术性能的首要因素是数据交换。传输的数据量应该尽量小,无论是压缩或去冗,或者其他技术。另一方面,发起一次网络调用会有很显著的网络开销。 设计网络API时,应该设计成“粗粒度”的——也就是说,最好一次调用返回大量数据,使得客户端发起的网络调用总数最小。这个原则与减少数据交换量相违背,所以必须做些权衡。

可以在前面股票RESTful Web服务平均响应时间的测试中观察到这种平衡。可以将服务设计成只返回一段时期内的基本数据(最高价、最低价、平均价和标准差),也可以设计成在返回这些基本数据的同时再加上这期间每天的日数据。

如果预先知道客户端要如何使用数据,就能很容易且精确地知道会返回哪些数据。但是,实际情况并不总是这样。在这个例子中,比如说客户端请求某只股票5年的历史数据,那开始时客户端应用只会向用户展示概要数据。如果用户想深入了解数据,查看单个股票的日数据,那会发生什么?是否所有数据都应该在第一次调用中返回给客户端,使得查看详情时无需再次发起网络调用?是否应该只返回概要数据,而在用户想要了解某年详情时,程序才再次发起调用获得那年的日数据?是否第二次调用应该获取整个5年的历史数据,即便此时用户只想看第三年的数据?

为了确定此处该用哪种策略,可以比较一下返回全部数据的时间和多次网络调用的时间。下表显示了在不同场景下获取数据的平均响应时间。

  1. 客户端请求1年的数据。
  2. 客户端请求1年的概要数据。
  3. 客户端请求5年的数据。
  4. 客户端发起2次请求:先请求概要数据,然后进一步请求特定时间的详细数据。
  5. 客户端发起10个请求:1个概要请求,加上9个特定时间详细数据的请求。

这些测试是在宽带连接下进行的。毫无疑问,网络速度对报告的时间有巨大影响。

各种场景下RESTful的平均响应时间
在这里插入图片描述

获取一整年完整数据的时间并不比只获取概要数据长太多,所以如果用户只需要获取其中的三个数据片段,那一次性返回整个数据集总是更好的选择。不过5年的概要数据有点不同:数据编组和发送所需的时间要长得多,所以在总时间达到平等前,用户需要发起11个获取详情的请求。

本例中的时间包括将RESTful服务返回的JSON数据编组的时间,这个时间取决于数据有多少年。但是多个客户端可能会请求相同的数据集,这种情况可以重用之前编好组的数据。如果编好组的数据已经计算好,响应时间的拐点就会有很大的不同,如下表所示:

各种场景下(响应有缓存)RESTful的平均响应时间
在这里插入图片描述
由于调用一次概要数据的开销基本不变,所以概要数据的响应时间差别很小。而获取1年和5年完整数据的时间只是在传输数据上,明显少于之前数据需要计算和编组的情况。一般来说,可以返回给客户端大量可能并不需要的数据,而没有太多性能上的损耗。

小结

Java EE应用的性能依赖于好几个因素。其中应用代码的质量永远是最主要的。而且,因为用到了许多外部资源,所以应用服务器的性能瓶颈通常并不在Java层。

许多影响应用服务器性能的因素并不只是针对Java EE——尤其是线程的性能、对象池和网络性能。对应用服务器而言,最重要的影响因素是它传输或处理的数据量——无论是简单的HTML,还是XML、序列化对象状态或JSON等。

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

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

相关文章

强大业务体系支撑,亚马逊云科技占据近八成中国企业出海总销量

从人类发展历史上看&#xff0c;无论是刳木为舟&#xff0c;剡木为楫&#xff0c;还是郑和下西洋&#xff0c;亦或是欧洲大航海时代&#xff0c;人类对于出海探索这件事就从未停止。而在如今的时代&#xff0c;相似的故事依旧在上演。过去的十年&#xff0c;是中国互联网最为繁…

一文了解AppSec,以及如何通过Perforce工具保障应用程序防护

应用程序防护&#xff08;AppSec&#xff09;是有效且高效的安全措施&#xff0c;有助于帮助软件应用程序解决日益严重的安全威胁。本篇文章将讨论应用程序防护&#xff08;AppSec&#xff09;的原理、最佳实践以及您应该使用什么AppSec工具。 什么是AppSec&#xff1f; AppS…

近视眼选择什么台灯好一点?高品质护眼台灯推荐

目前我国儿童以及青少年的近视率达到53.7%&#xff0c;且近视发病率不断呈现低龄化趋势&#xff0c;导致近视的主要是因为用眼过度。而电子产品的普及&#xff0c;网课、打游戏、刷短视频等&#xff0c;被许多家长认为是导致近视的主要原因&#xff0c;其往往忽略掉了一个很重要…

springboot社区服务系统-计算机毕设 附源码77279

springboot社区服务系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&a…

Unity游戏开发之游戏动画(模型动画制作及导入)

一. 简单制作3D角色 在stream中下载Fuse软件在Fuse中制作人物&#xff0c;导出模型为OBJ格式&#xff08;注意&#xff1a;这里导出目录必须为英文路径&#xff0c;否则只能导出空的OBJ文件&#xff09;压缩Obj文件为zip格式打开Mixamo网站&#xff1a;https://www.mixamo.com…

刷题日记04《回溯算法》

回溯算法本质 回溯算法的本质是穷举&#xff0c;即对所有可能的情况进行一一穷举&#xff0c;如果求解过程中发现某个情况不符合求解要求&#xff0c;直接进行剪枝即可 回溯算法模板 我们可以将回溯算法理解为以下两种模板 1.递归回溯 result [] def backtrack(路径, 选择列表…

企业电子招投标系统源代码之电子招投标系统建设的重点和未来趋势+spring clould +java+二次开发

计算机与网络技术的不断发展&#xff0c;推动了社会各行业信息化的步伐。时至今日&#xff0c;电子政务、电子商务已经非常普及&#xff0c;云计算、大数据、工业4.0、“互联网”等发展理念也逐步深入人心&#xff0c;如何将传统行业与互联网科技有效结合起来&#xff0c;产生1…

港联证券:新能源汽车再迎助力 科技巨头持续加注机器人领域

上周五&#xff0c;A股再度反弹拉升&#xff0c;两市股指盘中全线走高&#xff0c;沪指突破3200点&#xff0c;深成指涨逾1%&#xff0c;创业板指一度涨超2%。截至收盘&#xff0c;沪指涨0.62%报3200.06点&#xff0c;深成指涨1.02%报11026.59点&#xff0c;创业板指涨1.6%报22…

【梦辛工作室】java实现简易消息队列处理器 可分区 分区顺序消费MxMQ

大家好哇&#xff0c;又是我&#xff0c;梦辛工作室的灵&#xff0c;最近在巩固JUC并发包&#xff0c;突然想到如果自己的应用体量不大&#xff0c;但有需要消息队列来实现应用解耦和削峰来缓解服务器突增压力&#xff0c;比如抢票时&#xff0c;突然有比较用户同时抢票&#x…

C++之GNU C的__attribute__((constructor))优先级使用(一百四十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

C++ 设计模式----“对象性能“模式

“对象性能”模式 面向对象很好地解决了“抽象”的问题&#xff0c;但是必不可免地要付出一定的代价。对于通常情况来讲&#xff0c;面向对象的成本大都可以忽略不计。但是某些情况&#xff0c;面向对象所带来的成本必须谨慎处理。 典型模式 Singleto Flyweighta Singlet…

51单片机笔记

51单片机笔记 一、编程区域 1.1 用户应用程序区&#xff08;AP区&#xff09; 是指用户自己编写的程序区 1.2 ISP监控程序区&#xff1a; ISP区是指芯片出厂时就已经固化在单片机内部的一段程序&#xff0c;STC单片机可以进行ISP串行下载程序&#xff0c;这就是因为芯片在出…

在Blender和Zbrush中创建激光指示器,新手硬表面建模码住!

大家好&#xff0c;今天云渲染小编给大家带来的分享是硬表面建模&#xff0c;CG艺术家Lyubov使用Blender和Zbrush创建激光指示器的幕后花絮。 介绍 我叫 Lyubov&#xff0c;来自俄罗斯圣彼得堡&#xff0c;是一名 3D 建模的初学者。虽然学习还不到一年&#xff0c;但是我对它…

etcd安装

ETCD安装 windows版本 下载 下载地址https://github.com/etcd-io/etcd/releases 安装 其实也不用安装&#xff0c;下载解压后&#xff0c;得到如下 选中etcd.exe&#xff0c;右键→属性→兼容性→以管理员身份运行此程序勾上&#xff0c;当然&#xff0c;每次运行时候右键…

kettle作业循环实现

kettle作业循环实现 使用kettle作业中的JavaScript实现作业循环&#xff0c;这里是固定循环10次 JavaScript2 parent_job.setVariable("max",10); parent_job.setVariable("count",1); true;检验字段的值 JavaScript var current parent_job.getVari…

MySQL事务+存储引擎

文章目录 MySQL事务存储引擎1 事务1.1 事务的概念1.2 事务的ACID特点1.3 导致问题1.4 事务控制语句1.4.1 查看修改隔离级别1.4.2 使用set设置控制事务1.4.3 查看事务自动提交功能 2 存储引擎2.1 存储格式2.2 常用存储引擎2.3 查看表使用的存储引擎2.4 修改存储引擎2.5 InnoDB行…

证券市场基本概念

证券市场基本概念 一、 指数分类1.1 什么是指数1.2 指数分类 二 、交易所及板块2.1 交易所及板块2.2 股票代码规则 三 、指数、ETF、股票的关系3.1 指数和股票的关系3.2 指数和指数ETF的关系3.3 ETF概念 四、 股票行业分类4.1 申万行业分类4.2 股票与申万行业分类的关系 五 、指…

idea - 插件之 codeium(安装篇)

idea - 插件之 codeium 插件官网地址&#xff1a;https://codeium.com/ Idea 版本&#xff1a;2021.3.2 关于插件作用就不多做介绍&#xff0c;接下来开始正文。 由于目前有很多博客文章没有对 Idea 安装进行详细的讲解和遇到问题的处理讲解&#xff0c;所以我经过踩坑后&am…

【C++学习】C++的动态内存管理 | new和delete的底层 | 初识模板

目录 1. C的动态内存管理 2. new和delete的底层 3. 定位new 4. new和malloc 的区别总结 5. 模板 写在最后&#xff1a; 1. C的动态内存管理 上一篇文章已经大致介绍完new和delete的用法&#xff0c; 以及C和C语言两种动态内存管理方式的区别&#xff0c;这里简单总结一…

【MMCV python安装指南】

MMCV python安装指南 MMCV 介绍安装教程1.系统环境2.python版本3.torch版本4.mmcv版本 安装示例 MMCV 介绍 mmcv 是用于计算机视觉研究的基础 Python 库&#xff0c;支持 MMLAB 中的许多研究项目&#xff0c;例如 MMDetection https://github.com/open-mmlab/mmdetection MMAct…