原因是最近做的一个项目中,报Stack overflow了,这几天把windows下的内存分配看了一下,还有几点不理解,恳请大家一起讨论下。现在将复杂的问题抽象成一个简单的问题。在项目中,有一个MessageAction的类,里面一个方法getMessageByWhereid(int id);项目中多个页面会调用这个类的getMessgeByWhereid()方法。那么我们来分类讨论这个问题。一、假如这个Message类是非单例的
接在假设,在项目的首页中多处调用这个方法,假如这个首页是有IndexAction类管理的,那么我们可以选择两种方法来实现:
1. 使用new来实现,即在IndexAction中,
MessageAction messageAction = new MessageAction();//第一处位置Id为1的调用
result1 = messageAction.getMessageByWhereid(1);//第二处位置Id为2的调用
result2 = messageAction.getMessageByWhereid(2);//第三处位置Id为3的调用
result3 = messageAction.getMessageByWhereid(3);那么当一个用户访问这个页面的时候,会执行上面的三个方法,windows会在堆中为messageAction这个对象建立一个内存区域,然后每调用一次getMessageByWhereid()方法,就会相应的在栈空间建立一块内存区域,用来存储该方法的参数和返回值,也就是说用户访问这个页面的时候,内存是这样分配的,在堆中建立了一块区域,存放messageAction这个实例,在栈中建立了三块区域,分别存放这三次调用方法时产生的参数和返回值,我现在的理解是这样的,如果不对,请指正!那么问题来了,当有一万个用户访问这个页面的时候,岂不是要在内存的堆空间中建立一万个messageAction对象,同时在建立了三万个栈空间,虽然这三万个栈空间相互独立,互不影响,但是我有些怀疑,请问事实是这样的吗?2. 使IndexAction继承自MessageAction类,写到这里,感觉这个和new出来的没多大差别,先放一放。二、我们假设这个MessageAction类是单例的
就是不管有多少用户访问首页,都只会产生一个messageAction对象,当每个用户访问这个页面时,服务器针对每一个用户的额请求,都会创建或从线程池里复用一个线程,每个线程都会调用自己的getMessageByWhereid()方法,也就是说每一个getMessageByWhereid()方法的执行,都有自己的栈空间,不会存在并发的问题,这是我现在的理解,不知道是不是这样的?但是在实际的使用过程中,在页面中只调用一次getMessageByWhereid()方法,没有任何问题,但是如果调用两次或者两次以上,就会出现栈溢出的问题,我在想,既然每次执行getMessageByWhereid()方法,都会有属于自己的栈空间,那么为什么会出现这种问题,我的getMessageByWhereid()方法中使用了一个较复杂的递归,百思不得其解,来CSDN,请各位高手不吝赐教!