finally遇到的坑
前言
finally这个关键词在我个人开发过程中实际上并不算是真正使用过,虽然之前在理论学习的时候调试过finally到底是怎么回事:
http://blog.csdn.net/xiaoxiaoxuanao/article/details/52573859
但是在实际开发过程中如果真的遇到问题,并且和很多框架结合起来的话,这么简单的问题往往不容易被很容易的发现,很多时候会怀疑是不是那些框架结合起来导致的,而不是考虑代码本身是不是有问题。
第一次finally引发的问题
finally+redis
问题描述:
这个问题是一个线上的事故,在之前的博客里面描述过:
http://blog.csdn.net/xiaoxiaoxuanao/article/details/52692614
问题发生在使用redis链接的时候,通过jedis原生代码获取redis连接,想法是执行完redis操作后再finally里面做资源回收,但是不幸的是开发人员因为经验不足,将获取redis连接的部分拿到了try外面,导致finally中的代码没有执行。
代码如下:
这个错误导致线上出现了并发问题,redis连接数迸发,导致新进来的request一直等待redis连接。而tomcat连接数实际上是有限的,如果并发访问过程过超过了tomcat负载,线上大面积502了。排查过程中也花费了大量的时间。
第二次finally引发的问题
fianlly+curator+spring
最近在学习curatorframework,curator是一个开源的zookeeper客户端,这个框架可以非常方便的对zookeeper节点进行监听。
问题描述:
问题发生在节点监听上,因为之前从未接触过使用curator,最近要用,所以在官网上下载了监听父节点的例子,给出的例子如下:
遗憾的是图片没有更清晰的了。
描述一下这段代码的由来:
- 这个start方法是写在spring框架里面的,需要在服务启动的时候执行。所以楼主第一个想法是加一个@component注解,写在构造方法里面。期望pathchildrencache 执行start的时候能够一直保持对/example节点的监听。 —失败
- 既然写在构造方法里面不行,就用spring的init-method去执行。期望监听的线程可以一直保持。 —失败
- 然后就开始怀疑是spring执行完初试化后线程退出。。然后就走错了方向。一直在找有没有什么applicationContext启动的时候可以一直使得线程保持。。
- 找了半天没找到之后想要不在这个线程里面加一个while(true)试试。
于是就成了上面截图中的代码。但是很显然,在代码中写个while(true)像什么样子,正准备请教大神的时候忽然发现是不是finally导致的。很可能在方法执行完成后jvm回收了finally中的client 和cache,导致之前注册的监听失效了。
去掉finally中的代码之后果然监听成功了。但是代码中的client和cache都是方法级别的,方法执行完成之后,是不是也会gc调client和cache呢?如果gc掉了为什么对监听不造成影响?这些问题还有待慢慢研究。
总结
上面的两个问题一个是资源没有被回收导致的,一个是资源被回收导致的,所以平时在使用finally的时候一定要特别注意,在合适的时候让资源被回收。遇到问题的时候也要仔细的看代码想原理,尤其是对于那些自己不熟悉的。
ps:上面第二图中的代码还有一个非常明显的问题:将获取client的语句放在了方法内部,幸好start方法在spring容器启动的时候只被调用一次,不然势必出现并发问题,以后开发的时候一定要注意这种获取资源的代码放在类级别。
finally遇到的坑相关推荐
- 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)
目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...
- java调用clang编译的so_写Java这么久,JDK源码编译过没?编译JDK源码踩坑纪实
好奇害死羊 很多小伙伴们做Java开发,天天写Java代码,肯定离不开Java基础环境:JDK,毕竟我们写好的Java代码也是跑在JVM虚拟机上. 一般来说,我们学Java之前,第一步就是安装JDK环 ...
- flask sqlalchemy踩坑记录
查询 坑1: 查询不存在返回值不全是None 当使用first().one()等函数进行查询时,如果查询不存在,返回值为None 但是如果使用all().paginate()等函数进行查询是,如果返回 ...
- mac git使用与配置踩过的坑
#mac git使用与配置踩过的坑 标题mac配置git ssh密钥 参考链接mac配置git ssh key go get安装失败的解决方法 go get约等于git clone+go instal ...
- 你需要掌握的有关.NET DateTime类型的知识点和坑位 都在这里
引言 DateTime数据类型是一个复杂的问题,复杂到足以让你在编写[将日期从Web服务器返回到浏览器]简单代码时感到困惑. ASP.NET MVC 5和 Web API 2/ASP.NETCo ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得
该文章出自:http://www.cnblogs.com/hucn/p/3572384.html 分析工具:http://www.blogjava.net/jjshcc/archive/2014/03 ...
- Python 常见的坑汇总
1. 列表与 * 操作 Python 中,* 操作符与 list 结合使用,实现元素复制. 复制 5 个空列表: In [1]: [[]] * 5 Out[1]: [[], [], [], [], [ ...
- 20150726 填坑日记
三中内填坑: 1. 组合数递推什么的 C(m,n)=C(m,n-1)+C(m-1,n-1).填了个大坑,以前没认真听课QAQ 2. 裸题过河卒 3. 缺角正方形摆放车统计,分上下部分,枚举上部分放几个 ...
- yolact_ros出坑记录
教程:https://github.com/Eruvae/yolact_ros 下载通信中的话题msg 创建虚拟环境 conda create -n yolact python=3.7.10 cond ...
最新文章
- 如何下载DELL服务器VMware ESXi镜像
- 12.PHP_PDO数据库抽象层
- 解析Excel2007之Style、Drawing、Chart
- JDBC驱动的动态加载
- 信息管理系统 github_Java+MySQL实现学生信息管理系统
- Kubernetes—配置管理ConfigMap(十三)
- dao层如何调用对象_以k8s集群管理为例,大牛教你如何设计优秀项目架构
- php 转义字符处理,PHP转义与反转义字符串函数详解
- 时机论:早起的鸟儿也要选对“用户”季节
- IT编程从零开始学入门到精通需要多久
- 图像处理之图像质量评价指标SSIM(结构相似性)
- 为什么好多人说win8不好用?
- 在Win2003下安装WMP10有奇招
- 奋斗在美国湾区,码农的生活
- [凯圣王]减脂挑战第15天变化/饮食思路分享/碳水循环+轻断食/GI值和GL值的应用/碳水后置的理论基础
- web前端的css示例
- SVN报错Cleanup问题解决:Cleanup failed to process the following paths:Can‘t revert
- 产品周报第29期|创作中心优化:发文助手新增质量分检测功能,博文增加内容历史版本
- 如何搭建Jenkins导出Unity安卓环境
- socket服务端同时监听多个端口号
热门文章
- 【STM32G431RBTx】备战蓝桥杯嵌入式→扩展模块→DHT11
- python t检验显著差异_两组数据的均值是否具有显著差异的T检验
- oracle 朱志辉_《DB2设计、管理与性能优化艺术》(王飞鹏,李玉明,朱志辉,王富国)【摘要 书评 试读】- 京东图书...
- 偶数计算Python
- discriminative training鉴别性训练
- Rainbow Crack在windows生成彩虹表并破解Hash值
- 常用工业以太网协议性能及应用
- Aircrack-ng: (2) WEP WPA/WPA2 破解
- 【Linux】mjpg-streamer 源码分析
- 汉尼拔,刻画的真好!