我们经常看到一些 Java 性能优化的书或者理念,说不要在循环内定义变量,这样会占用过多的内存影响性能,而要在循环外面定义。接触 Java 这么久以来,相信很多 Java 程序员都被这种代码性能优化策略所误导。

看下面两个示例,示例1在循环外定义变量,示例2是在循环内定义变量。

/**
* 循环外定义变量
*/
private static void outer() {
Javastack javastack = null;
for (int i = 0; i < 10; i++) {
javastack = new Javastack();
}
} /**
* 循环内定义变量
*/
private static void inner() {
for (int i = 0; i < 10; i++) {
Javastack javastack = new Javastack();
}
}

先来分析这两个示例吧。

循环外定义变量

循环外定义变量,变量循环内每次引用指向不同的对象实例,每次循环变更对象实例时,上一次被指向的对象就会被销毁,直到最后一个循环。这样,循环结束后,这个变量还存在,并指向循环内最后一个对象实例,其他对象都销毁了。

这样,本应该是循环体内的生命周期变量被扩散到了循环外,如果循环外依旧用这个变量,会导致后面的业务发生不可预知的后果。这种问题在笔者工作当中经常会遇到,看下面的例子。

/**
* 循环外定义变量
*/
private static void outer() {
Javastack javastack1 = null;
for (int i = 0; i < 10; i++) {
javastack1 = new Javastack();
} Javastack javastack2 = userDao.getUser(10); }

上面定义了一个 javastack2 ,如果此时在后续代码或者传递到别的方法时写错了,用了 javastack1,那这时不就有问题了吗?这只是一方面,还有如果用同一变量名,当这一变量被重用时发生异常,本来发生异常应该是 null 值的,结果得到了是之前循环体内的值。

循环内定义变量

循环内定义变量,和循环外略有不同的是,每次都会创建新的局部变量指向新的对象实例,每个变量和对象的生命周期仅限于在循环体之内,而且每次循环结束该局部变量和对象实例都会随着循环体的结束而销毁,所以不存在占用更多的内存这一说法。

总结

两种用法都会创建相同数量的对象实例,只不过循环内会反复创建相同数量的局部变量,栈内存垃圾回收频率也会更高,但对于堆垃圾回收带来的性能影响和变量生命周期带来的业务影响来说,栈内存这点性能影响可以忽略不计。

所以,建议使用循环内定义变量,这种把变量的生命周期限制在循环体范围内,也不会出现业务上重用变量而导致严重的问题。

推荐:Spring Boot & Cloud 最强技术教程

90 % Java 程序员被误导的一个性能优化策略的更多相关文章

  1. Spring AOP注解为什么失效?90%Java程序员不知道

    使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方加,不然不会生效. 如下面几种场景 1.Controller直接调用Se ...

  2. 正式工作的前奏——一个Java程序员的实习总结(1)

    不知不觉,到深圳实习已经三个礼拜了.跟在暑假的三个半月实习不一样,这次收获更多,感受更好,算是摆脱了那次实习给我带来的阴影(这个会放到以后才说). 在知乎上,有这么一个问题,你现在最想跟刚工作时的你说 ...

  3. 一个3年Java程序员的坎与选择

    前言 LZ 15年本科毕业,不知不觉3年过去了,去年底裸辞回到成都来发展,年后开始找工作,面试了几家公司,现在整理整理做个总结,也方便规划下一个3到5年以及和广大想要进阶的Java程序员同胞们共勉. ...

  4. 做为一个Java程序员,你需要哪些傍身的技能?

    最近总有些断断续续的思考,想想从我入行以来,我到底学会了什么,做成过什么,以后要做什么,如何提升自己······· 工作3年了,常听人说3年,5年,10年是程序员的坎,每过一个都会有新的想法,新的改变 ...

  5. 如何成为一个优秀的java程序员

    Java程序员有许多应遵循的守则或最佳实践方式.本文概述了每个开发者最应该遵循的10条守则或戒律,如果不遵循它们,将会导致灾难性后果. 1. 为代码添加注释(Add comments to your ...

  6. 一个10年Java程序员的年终总结,献给还在迷茫中的你

    我越来越担心我作为一个Java程序员的未来. 恍然间,发现自己在这个行业里已经摸爬滚打将近10年了,原以为自己就凭已有的项目经验和工作经历怎么着也应该算得上是一个业内比较资历的人士了,但是今年在换工作 ...

  7. 0~5年一个Java程序员的晋升之路

    在程序界流行着一种默认的说法叫“黄金5年”,也就是一个程序员从入职的时候算起,前五年的选择直接影响着整个职业生涯中的职业发展方向和薪资走向,如何走好这5年,彻底从一个刚入行的菜鸟蜕变成可以以不变应万变 ...

  8. 对于长沙互联网发展,一个外来两年Java程序员的所见所感所愿

    惟楚有材,于斯为盛 本文有感于2019长沙互联网求职招聘大会,内容比较多,但都是我自己的一些所见.所感和所愿. 2019年3月的最后一天,参加2019长沙互联网求职招聘大会,看到了很多的招聘企业,也看 ...

  9. (转)java程序员进入名企需要掌握哪些,立一个flag

    想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,在面试之前到底需要准备哪些东西呢?面试时面试官想了解你的什么专业技能,以下都是一个合格Java软件工程师所要具备的. 一.专业技能 熟练的 ...

随机推荐

  1. 虚拟网络VDC与VPC

    当前互联网行业,内部 IT 基础资源云端化是主要趋势.云平台将资源管理抽象出来,比如云主机.云 DB 等,以服务的方式提供给用户,按需使用,从而带来更大的灵活性与经济性. 随着主机.DB.缓存.存储等 ...

  2. IOC 和DI(转载)

    IOC 是什么? Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内 ...

  3. FortiGate高校图书馆SSLvpn配置案例

    1.组网及需求 某高校有一台FGT系列防火墙放置于互联网出口,拓扑如下图: 现需求通过组建sslvpn web代理模式和隧道模式以实现: 1.web代理模式:能访问 http://lib.xxxx.e ...

  4. Linux module 添加到bashrc 和临时ifort编译器 以及python2和3的配置

    第一步vim ~/.bashrc按键盘的i然后source /home/export/online1/bjpara/para/modules/scripts/cn-module.sh最后:x! bas ...

  5. [JAVA]JAVA章2 IOC与AOP是啥

    使用Spring框架的过程中,其实就是为了使用IOC(依赖注入),和AOP(面向切面编程),这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式. IOC就是典型的工厂模式,通过ses ...

  6. 目录命令(tree)

    TREE 命令: // 描述: 以图形方式显示驱动器中路径或磁盘的目录结构. // 语法: tree [<Drive>:][<Path>] [/f] [/a] // 参数: / ...

  7. Vue post提交

    vue中的axios 是不直接支持post方法的,所以我们得绕一下路,我目前在登录的时候运用到了,服务器端用php,可以收到数据 let param = new URLSearchParams(); ...

  8. 在excel中如何利用vba通过网址读取网页title(网址是https的)?

    昨天在百度知道上提了这个问题,我保存了些百度知道我回答的网址,想利用excel直接读取出网址的title,请问vba代码怎么写?(要支持https的) excel大神帮我回答了,在这记录下: Func ...

  9. hive、sqoop、MySQL间的数据传递

    hdfs到MySQL csv/txt文件到hdfs MySQL到hdfs  hive与hdfs的映射: drop table if exists emp;create table emp ( id i ...

  10. C++中的return和exit区别

    在main函数中,return和exit经常混用,两者的一个区别:return会执行statck unwinding,而exit不会.如果触发了信号,exit也同样不会做stack unwinding ...