Java代码优化ppt课件
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用java工具:jmap,jstack,jprofiler等
4、优化完后测试功能!
代码优化实践
运行更快 1.告警统计效率优化( jstack,内存换效率) 2.DataWorker线程抽象 3.DataWorker缓存读写分离 内存更小 1.Smatcher内存问题 2.Java对象占用内存 先预防,再优化
预防大于优化。
1、明确优化目标
代码优化步骤
在优化工作开始的时候,你还尚未明确优化内容和目的,那么你很容易陷入误区。在一开始,你就应 该清楚地了解你要达到的效果,以及其他优化相关的各种问题。这些目标需要明确指出(至少精通技术 的项目经理可以理解和表达它),接下来,在整个优化过程中,你需要坚持这些目标。
告警统计效率优化 其他方法:使用JavaVisualVM/Jprofiler查看方法耗时
DW线程优化 问题:DealThread,SendDataThread等都用Queue传递数据
方法:抽象、继承
DW线程优化
修改前
修改后
DWBiblioteka Baidu程优化
抽象后可以 1.重复代码降低 2.统一的异常判断,catch 3.Package调整,统一的日志记录 4.统一的speed实现 5.统一的心跳信息处理
明确为什么优化。现场问题触发,维护工作量大等等
优化是要朝着好的方向发展而不是过度地优化,过度优化会降低程序 可读性,会给后期维护人员增加难度系数。满足实际需要即可,不要为 了优化而优化。 要对优化的对象,进行测试或者有一定的深入理解。有 些api人家的单线程效率就非常高,你为了优化,写了一堆多线程,然后 各种锁,各种问题。。。。。
3、找到优化的关键点
这是有效优化的关键。找到项目中与你的目标(性能、资源或其他)相背的地方,并将你的努力和 时间用在那里。举一个典型的例子,一个Web项目速度比较慢,开发者在优化时将大部分精力放在了数 据库优化上,最终发现真正的问题是网络连接慢。另外,不要分心于容易实现的问题。这些问题尽管很 容易解决,但可能不是必要的,或与你的目标不相符。容易优化并不意味着值得你花费工夫。
2.AlarmCFPCache<cfp,fpList>增加本地缓存,提升查询效率
DW缓存优化 封装完,代码量依然很大,而且日志不方便,继续拆分:
1.alarmService负责写操作,cacheService负责读操作
好处:
DW缓存优化
1.写和读分离
2.实时告警处理和告警查询日志分开
3.写增加线程处理,读增加cache处理
原生类型(primitive type)的内存占用如下:
Primitive Type Memory Required(bytes)
boolean
1
byte
1
short
2
char
2
int
4
float
4
long
8
double 8
reference类型在32位系统上每个占用4bytes, 在64位系统 上每个占用8bytes。
DW缓存优化
公共方法抽象 Cache分类实现 读写分离
DW缓存优化 1.1个类2000多行代码,好多重复操作,先抽象公共方法
Cache分类实现 1.AlarmCache在1406,ack,1409等各种消息里重复操作
2.ClearCache在1406,手动清除等各种消息重复操作
Cache分类实现 1.AlarmCache封装了活动告警/1409/清除告警的插入,活动放7天,清除3小时
如果是double[],数据量增加额外开销可以忽略不计
结论: 1. 集合带来便利的同时,有好多额外的开销 2. 选择适当的集合。 3. set底层为啥不用数组实现?map? 4. 100w以上数据考虑第三方集合实现Trove
旧方案
for $ne in neList{ id= ne.id cls=ne.object_class alarm= alarmmap.get(id) //do some things
}
新方案
prepare:neMap for entry in alarmMap.entryset{
id= entry.key alarm= entry.value ne=neMap.get(id) cls=ne.object_class //do some things }
2、选择正确的优化指标
选择正确的指标,是优化的一个重要组成部分,你需要按照这些指标来测量优化工作的进展情况。如 果指标选择不恰当,或者完全错误,你所做的努力有可能白费了。即使指标正确,也必须有一些辨别。 在某些情况下,将最多的努力投入到运行消耗时间最多的那部分代码中,这是实用的策略。但也要记住, Unix/Linux内核的大部分时间花费在了空循环上。需要注意的是,如果你轻易选择了一个很容易达到的 指标,这作用不大,因为没有真正解决问题。你有必要选择一个更复杂的、更接近你的目标的指标。
Java代码优化
综合监控
代码优化原则 代码优化步骤 代码优化实践
代码优化
代码优化原则
代码优化是什么。代码优化是指对程序代码进行等价(指不改变程序 的运行结果)变换。程序代码可以是中间代码,也可以是目标代码。等 价的含义是使得变换后的代码运行结果与变换前代码运行结果相同。优 化的含义是最终生成的目标代码更加轻松自如(运行时间更短、占用空 间更小)地工作,时空效率优化。
问题:运行一S段m时a间t内c存h溢e出r内存问题
方法:jmap
Smatcher内存问题 1.zkClient$7就是监听数据变更的通知对象
2.进一步查找:居然有1w多个监听器 3.日志:不停的有新客户端注册过来,其实是一样的,新注册就会添 加listener。。。
结论:查看代码修改注册机制
Java对象占用内存了解
告警统计效率优化 数据:neList 1000w的网元集合,alarmMap<neId,alarm>10w的告警map
问题:根据object_class统计告警数,执行慢 方法:jstack,内存换效率 1.替换耗时的方法。 如:java的crc32换成 hadoop里的crc32 2.换一种思路实现,内存换效率
100个entries,cost 8.6k, 实际的double=2*100*8=1.6k
Double=16+8,double=8,67%额外开销
TreeMap包括: 48bytes+n*40bytes(entry)
double[]包括: 16+100*8
扩大数据量到1w
数据量增加额外开销并没有降低
4、优化完后测试功能!
代码优化实践
运行更快 1.告警统计效率优化( jstack,内存换效率) 2.DataWorker线程抽象 3.DataWorker缓存读写分离 内存更小 1.Smatcher内存问题 2.Java对象占用内存 先预防,再优化
预防大于优化。
1、明确优化目标
代码优化步骤
在优化工作开始的时候,你还尚未明确优化内容和目的,那么你很容易陷入误区。在一开始,你就应 该清楚地了解你要达到的效果,以及其他优化相关的各种问题。这些目标需要明确指出(至少精通技术 的项目经理可以理解和表达它),接下来,在整个优化过程中,你需要坚持这些目标。
告警统计效率优化 其他方法:使用JavaVisualVM/Jprofiler查看方法耗时
DW线程优化 问题:DealThread,SendDataThread等都用Queue传递数据
方法:抽象、继承
DW线程优化
修改前
修改后
DWBiblioteka Baidu程优化
抽象后可以 1.重复代码降低 2.统一的异常判断,catch 3.Package调整,统一的日志记录 4.统一的speed实现 5.统一的心跳信息处理
明确为什么优化。现场问题触发,维护工作量大等等
优化是要朝着好的方向发展而不是过度地优化,过度优化会降低程序 可读性,会给后期维护人员增加难度系数。满足实际需要即可,不要为 了优化而优化。 要对优化的对象,进行测试或者有一定的深入理解。有 些api人家的单线程效率就非常高,你为了优化,写了一堆多线程,然后 各种锁,各种问题。。。。。
3、找到优化的关键点
这是有效优化的关键。找到项目中与你的目标(性能、资源或其他)相背的地方,并将你的努力和 时间用在那里。举一个典型的例子,一个Web项目速度比较慢,开发者在优化时将大部分精力放在了数 据库优化上,最终发现真正的问题是网络连接慢。另外,不要分心于容易实现的问题。这些问题尽管很 容易解决,但可能不是必要的,或与你的目标不相符。容易优化并不意味着值得你花费工夫。
2.AlarmCFPCache<cfp,fpList>增加本地缓存,提升查询效率
DW缓存优化 封装完,代码量依然很大,而且日志不方便,继续拆分:
1.alarmService负责写操作,cacheService负责读操作
好处:
DW缓存优化
1.写和读分离
2.实时告警处理和告警查询日志分开
3.写增加线程处理,读增加cache处理
原生类型(primitive type)的内存占用如下:
Primitive Type Memory Required(bytes)
boolean
1
byte
1
short
2
char
2
int
4
float
4
long
8
double 8
reference类型在32位系统上每个占用4bytes, 在64位系统 上每个占用8bytes。
DW缓存优化
公共方法抽象 Cache分类实现 读写分离
DW缓存优化 1.1个类2000多行代码,好多重复操作,先抽象公共方法
Cache分类实现 1.AlarmCache在1406,ack,1409等各种消息里重复操作
2.ClearCache在1406,手动清除等各种消息重复操作
Cache分类实现 1.AlarmCache封装了活动告警/1409/清除告警的插入,活动放7天,清除3小时
如果是double[],数据量增加额外开销可以忽略不计
结论: 1. 集合带来便利的同时,有好多额外的开销 2. 选择适当的集合。 3. set底层为啥不用数组实现?map? 4. 100w以上数据考虑第三方集合实现Trove
旧方案
for $ne in neList{ id= ne.id cls=ne.object_class alarm= alarmmap.get(id) //do some things
}
新方案
prepare:neMap for entry in alarmMap.entryset{
id= entry.key alarm= entry.value ne=neMap.get(id) cls=ne.object_class //do some things }
2、选择正确的优化指标
选择正确的指标,是优化的一个重要组成部分,你需要按照这些指标来测量优化工作的进展情况。如 果指标选择不恰当,或者完全错误,你所做的努力有可能白费了。即使指标正确,也必须有一些辨别。 在某些情况下,将最多的努力投入到运行消耗时间最多的那部分代码中,这是实用的策略。但也要记住, Unix/Linux内核的大部分时间花费在了空循环上。需要注意的是,如果你轻易选择了一个很容易达到的 指标,这作用不大,因为没有真正解决问题。你有必要选择一个更复杂的、更接近你的目标的指标。
Java代码优化
综合监控
代码优化原则 代码优化步骤 代码优化实践
代码优化
代码优化原则
代码优化是什么。代码优化是指对程序代码进行等价(指不改变程序 的运行结果)变换。程序代码可以是中间代码,也可以是目标代码。等 价的含义是使得变换后的代码运行结果与变换前代码运行结果相同。优 化的含义是最终生成的目标代码更加轻松自如(运行时间更短、占用空 间更小)地工作,时空效率优化。
问题:运行一S段m时a间t内c存h溢e出r内存问题
方法:jmap
Smatcher内存问题 1.zkClient$7就是监听数据变更的通知对象
2.进一步查找:居然有1w多个监听器 3.日志:不停的有新客户端注册过来,其实是一样的,新注册就会添 加listener。。。
结论:查看代码修改注册机制
Java对象占用内存了解
告警统计效率优化 数据:neList 1000w的网元集合,alarmMap<neId,alarm>10w的告警map
问题:根据object_class统计告警数,执行慢 方法:jstack,内存换效率 1.替换耗时的方法。 如:java的crc32换成 hadoop里的crc32 2.换一种思路实现,内存换效率
100个entries,cost 8.6k, 实际的double=2*100*8=1.6k
Double=16+8,double=8,67%额外开销
TreeMap包括: 48bytes+n*40bytes(entry)
double[]包括: 16+100*8
扩大数据量到1w
数据量增加额外开销并没有降低