感冒了,在家里休息,打开电脑随便看看,想起前两天有人问的一个事情:“内存溢出怎么分析和处理?”方案有很多了,基本上的思路就是获取系统状态,内存变化方向,内存对象等之类的,profile,debug,jmx,dump等等。
我更想说的是,为什么会内存溢出呢?
在我看来,干活有两种方式:
一般来说,我都是后者,所以真的很少碰到各种莫名其妙的问题,比如自己实现排序算法、在内存中处理有100000个值的列表、不用第三个变量来交换两个变量的值等等。
吐槽完毕,来说说对于内存溢出这种事情是要怎么避免,我所谓的“想清楚了再开干”到底是怎么想清楚的。
首先内存溢出的本质是什么?“内存使用超出了预期”。
那么要怎么避免呢?“预期内存怎么使用,将其控制在内存使用范围呢”。
Java程序中,内存是被怎么占用的?被数据和对象占用的,数据和对象怎么来的?
思路和应用输入和输出怎么控制所说的是一样的,控制线程数,使用缓存控制。
思路也是一样的,线程数,缓存,再加上生存时间,对象池等等。
使用上述技巧和思路你就能控制好你应用中的内存了,但是所有的设计都是在风险和满足需求之间的平衡,如果再退一步,那么你需要考虑一下Java虚拟机中内存各个区的使用了。你需要区分好哪些是常驻对象,哪些是临时对象,新生代,旧生代,怎么安排你的虚拟机中各个内存区的大小。希望你不需要用到,如果需要的话,可以看看《深入理解Java虚拟机》这本书。
有这么一个应用,它获取客户端的请求,验证请求的合法性,然后对于合法的请求,从第三方系统获取文件内容,并把文件内容写回给客户端。
下面是一大片的空白,再滚动下去之前看我的设计之前,读者可以就这个需求想想你会怎么处理。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
第三方系统有两个,一个是合法性验证的,一个是文件内容的。
合法性验证的请求和输出的内容都比较小。但是考虑到其服务器的性能,把合法性验证的交互过程放到一个线程池中控制。这样能避免合法性验证服务不过来的情况。
文件内容第三方系统的输入和输出的控制
最原始的需求中还有一个把文件内容缓存在本地,然后可以多次写给客户端的这么一个想法,减少网络等待。这个想法被我否决了,原因如下:
想清楚了再开干就是这个意思,花点时间系统的想想,想清楚了,前面多写点代码,多写点单元测试,后面少点麻烦,不用救火,也不用加班。
吃饭去了。
再多啰嗦一句,《JUnit收费课程》的第二节的材料已经准备好了,昨晚担心自己的塞着鼻子,大家听着难受,没有录。今天好多了,晚上录一下,明天上午编辑审核,明天下午或者晚上大家应该就能看到了。
原文地址:http://blog.csdn.net/justfly/article/details/46416425