网站开发进阶 (九) 应用内存检测
一、前言
近来出现立马项目运行在阿里云 ECS(Elastic computer service
弹性计算服务)部署的tomcat
服务器中时,经常出现服务器宕机的现象。经过分析发现,有可能是由于项目中存在内存泄漏的情况,出于安全机制考虑,有可能是阿里云服务器的自我保护机制而出现服务器自动关闭的情况。
二、内存泄漏的发生方式
常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。
偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。
一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅有一块内存发生泄漏。
隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。
三、拓展阅读 JSP 两种声明变量的区别
在 JSP 中用两种声明变量的方法,一种是在<%! %>
内,一种是在<% %>
内。他们之间有什么区别呢?我们直接看一个 JSP 文件来理解。
代码如下:
启动tomcat
运行这个 jsp 会发现当我们不断刷新页面时count
的值会不断增加,而 i 的值始终不变,也就是说定义在<%!%>
内的变量会累加,而定义在<%%>
内的变量不会累加。
这是为什么呢?
声明在<%! %>
内的变量和方法是一个类内的变量和方法也就是成员变量和成员方法。声明在<%%>
内的变量是一个方法的变量也就是局部变量。
我们学习 JAVA 的时候就知道成员变量会被多个对象共享,而局部变量单独对象访问。所以 count 会自动增加,i 不对递增。
在这里还有个问题要告诉读者,如果在<% %>
内添加一个method()
方法那么该程序就会报错,其实原因不难想象,这样声明一个方法等于就是一个类里的方法里又声明了个方法。结果肯定是错误的。
注:jsp 页面中<%! %>
内定义的是全局变量。使用<%! %>
定义的变量编译成servlet
后成为servlet
的私有成员变量,在servlet
环境中,对于一个 JSP 页只允许有一个结果servlet
的实例在运行和响应所有的页面请求。
因此,servlet
中所有的成员变量可以被所有的请求所共享,所以只要成员变量没有重新赋值,下次访问该页面时仍然不变。而在<% %>
中定义的变量编译成servlet
后成为service()
方法的一个本地变量,而service()
方法中的本地变量只能每响应一次请求就重建一次。
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/4db81a2b34d016d0091c18b65】。文章转载请联系作者。
评论