论坛首页 Java企业应用论坛

使用Wicket开发网站出现内存溢出的讨论

浏览 7479 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-07  
本来是在新闻里的,不过觉得那里不合适讨论这种问题,所以另外开了一个新的帖子

greateWei说
wicket确实不错,基本上和桌面开发思想类似,一些常用的控件如Label、Tabbed Panel、Text、DateTime、Tree、Grid等上手使用非常方便,你可以做公用的panel,tree等,然后在多个页面中使用。

另外一个就是ajax支持对开发使用人员基本上是透明的,封装做的相当不错。

我觉得一般来说,wicket适合用于开发交互性比较强,用户操作比较复杂的应用管理类web应用,对于一般大流量、浏览性web网站不一定适合,主要原因wicket所有的状态采用session机制来保存管理,每个页面的状态也是保存在服务器端,这样一旦用户访问人数非常多的话,对服务器端压力非常大,特别是内存要求很高。

之前做了一个简单的外卖订餐网站(http://www.517wm.com),发现并发访问人数超过1500人左右时,经常性会发生内存溢出(tomcat 分配了 1G 内存,计算机内存是5G,使用普通PC机做服务器),要解决这个问题,估计只有通过tomcat集群或者一些其他jvm内存集群方案才能解决。


wl95421说
Wicket的性能并不差,给大家做个简单的分析,一般的页面,如果是用LoadModel,大概序列化后只占5-10K,每个Session中默认是放置5个页面,假设再开大一些,放置10页,也就是说对于每个Session来说,Wicket只占用100K左右的内存。

对于1500人的访问,即1500X100K,那么只占用150M内存,这个占用绝对不算大。
只不过对于大部分人来说,并不习惯使用LoadModel,所以将Model也Cache在Session中了,如果是列表数据,自然就大了很多,比如说一个25条数据的列表页面,序列化后肯定不是10K,至少也是个40K,搞不好100K,就算默认是5个页面,也要占用500K内存,1500个上来,就是750M,肯定完蛋。

所以如果出现这种情况,应该看LoadModel,而不是默认的Model。
另外如果情况不严重,可以考虑使用DiskSessionStore,性能也还不错。
再加一句,并不是所有的东西都需要放到Session中
多用一下StatelessForm,会发现对于互联网来说,这种更合适。

greateWei
to wl95421
去年年底也是看了你写的wicket用户手册入门的,之前还不了解wicket是干什么用呢,

之前确实没有使用LoadModel模式,主要是编码工作量问题吧,网站上线试用了一段时间后,随着资料增加和访问人数增加,内存溢出越来越频繁,后来基本上设计到大数据量列表的全部使用了LoadModel模式,不过内存问题还是存在的。

有几次,网站中一些搜索引擎爬虫收录时,并发数上去后,偶尔还是会发生内存溢出问题,我查看了硬盘中的session文件,发现大小基本上在300k左右,应该属于正常范围。

解决办法倒不是没有:
1.增加内存容量;不过tomcat在windows下似乎最大只能分配1G内存,linux应该没这个限制;
2.Terracotta也是一个选项;
3.session序列化机制改良,曾有人提出使用mem cache来实现;我现在使用的是默认session保存机制;

使用wicket一段时间,总的印象还是不错的。

原先主要做桌面应用软件开发的,发现切换到web开发挺自然的。ajax开发应用实在是方便,struts2虽然也有,当时看了基本上放弃使用struts2,主要是本人之前没有ajax开发调试经验;web部分代码重用非常方便,使用panel可以为你节省很多重复代码。

如果使用java开发web应用管理类网站,有频繁交互,需要有良好的用户体验,我觉得wicket、tapestry、GWT三个框架是首选,三个框架都有异曲同工之妙。
   发表时间:2009-08-07   最后修改:2009-08-07

我给几个建议,可以结合用:

  1. 1500人呢,不算太小,当然也远不算大,用台64位的PC服务器,JVM上到3-4G内存,应该问题就能解决了。
  2. Terracotta我不建议你使用,它的优势并非体现在这种不大不小规模的系统上,反而带入不必要的复杂度。
  3. 可以使用各种方式,如Profile,或者用DiskSessionStore来序列化Page,找到内存占用点,然后改正,比如说用Stateless控件。
  4. 序列化改良机制是一个不错的思路,但有一些技术风险,还是建议好好研究如何高效使用DiskSessionStore可能更合适。
  5. 我不知道你们的LoadModel是如何用地,我用得时候,是LoadModel中只放置一个Key值,然后用的时候通过Key值去数据库或者其它地方取,至于数据源则用它自己的缓存。

 

另外说每个页面如果是300K的话,我觉得肯定是有问题,比我假设的100K还要大上很多,也就难怪1500人会内存溢出了,还是建议多用LoadModel和Stateless控件。

0 请登录后投票
   发表时间:2009-08-07  
wl95421 写道

我给几个建议,可以结合用:

  1. 1500人呢,不算太小,当然也远不算大,用台64位的PC服务器,JVM上到3-4G内存,应该问题就能解决了。
  2. Terracotta我不建议你使用,它的优势并非体现在这种不大不小规模的系统上,反而带入不必要的复杂度。
  3. 可以使用各种方式,如Profile,或者用DiskSessionStore来序列化Page,找到内存占用点,然后改正,比如说用Stateless控件。
  4. 序列化改良机制是一个不错的思路,但有一些技术风险,还是建议好好研究如何高效使用DiskSessionStore可能更合适。
  5. 我不知道你们的LoadModel是如何用地,我用得时候,是LoadModel中只放置一个Key值,然后用的时候通过Key值去数据库或者其它地方取,至于数据源则用它自己的缓存。

 

另外说每个页面如果是300K的话,我觉得肯定是有问题,比我假设的100K还要大上很多,也就难怪1500人会内存溢出了,还是建议多用LoadModel和Stateless控件。

 

  1. 编码中,现在确实按第5点来实现的。使用了一段时间后的感想:wicket的loadModel使用起来编码工作量比较大,而且一般用户使用wicket可能往往直接使用普通model方式来实现,wicket团队似乎应该在文档中强调这一点;
  2. 300K指的一个用户session磁盘中保存的文件大小,而不是一个页面的session大小;
  3. 如果JVM内存使用大小可以调整到3-4G,这个问题应该不大;我现在使用windows xp 32位,tomcat内存最大只能设置到1G;

wicket使用了一段时间后,感觉wicket和hibernate有一个共同点:

  1. 需要在开发使用过程中,不断做性能调优;
  2. 细节往往会决定性能:如控件对象增加final关键字就会session持久化,而这一般不会注意;
  3. wicket的论坛非常友善,一般提交的问题第二天就有答案;常见的使用问题在论坛上找一找基本上能够解决的;

 

 

0 请登录后投票
   发表时间:2009-08-13  
引用
可以使用各种方式,如Profile,或者用DiskSessionStore来序列化Page,找到内存占用点,然后改正,比如说用Stateless控件。


今天又发生了内存溢出错误。

看了一下磁盘中的session持久文件,发现有20来个session文件大小有10m左右,但是看了看代码,基本上都是遵守上述规则的,不知如何来定位wicket的内存占用点呢?从session文件来看,好像发现不了什么问题。
0 请登录后投票
   发表时间:2009-08-14   最后修改:2009-08-15
原来的这部分内容有误导观众嫌疑,我先移除吧,下次清楚了,再补充,~
0 请登录后投票
   发表时间:2009-08-14  
我虽然觉得Wicket非常地好,适合快速开发。
但对于技术能力不强的公司,我倒是不推荐,因为其实里面隐藏了很多陷井。
想把stateful的内容用好,并不是一件简单的事情。

至于如何判断某个对象序列化后的对象很大,其实可以继承DiskSessionStore,然后在序列化的时候,检查一下哪一个对象的字节数组太大,就很容易定位了。
如果懒地话,直接改一个DiskSessionStore的代码也就是了。
0 请登录后投票
   发表时间:2009-08-15   最后修改:2009-08-15
wl95421 写道
我虽然觉得Wicket非常地好,适合快速开发。
但对于技术能力不强的公司,我倒是不推荐,因为其实里面隐藏了很多陷井。
想把stateful的内容用好,并不是一件简单的事情。


深有体会,入门快,但要用好,特别是内存管理一块有很多细节要注意。我现在是作为技术先锋做一个尝试性的实验项目,看看是否可以推广。

TO wl95421
您刚才提到stateless空间,目前wicket提供的只有两个statelesslink和statelessform,能够讲解一下stateless的一些典型应用场景和注意事项。我现在用到的有两处:一个是登录框,另外一个是一些静态页面,在page构造函数中添加了setstatelesshint(true);这方面好像wicket资料很少讲到。

另外发现stateless应用有很多局限性,如只要在页面中放了一个stateful组件(如ajaxlink),那整个页面即使设置了statelesshint=true,也是以stateful方式处理的,最近一直在调优这方面的内容,发现如果设置了setVersioned(false),即只有一个版本的页面内容放入session,session的磁盘文件要小很多,不知道这样使用是否有副作用。这样的话那不是很多wicket的功能都无法使用了。

不知道上面的理解是否有问题?




0 请登录后投票
   发表时间:2009-08-15  
另外,其实很多场景都不需要将页面保存到session中,但如果使用了一些stateful控件,很多页面wicket都默认写入session了,不知不觉整个session文件就非常大了。
0 请登录后投票
   发表时间:2009-08-15  
请问你们遇到溢出的时候,有对JVM内存使用情况进行分析吗?不会是别处的内存泄漏吧!建议把内存快照拿下来进行分析,不然很难确定是什么东西造成的泄漏。
优化很重要,必须确定合适的内存大小、堆大小,太大太小都不好。
0 请登录后投票
   发表时间:2009-08-15  
魔力猫咪 写道
请问你们遇到溢出的时候,有对JVM内存使用情况进行分析吗?不会是别处的内存泄漏吧!建议把内存快照拿下来进行分析,不然很难确定是什么东西造成的泄漏。
优化很重要,必须确定合适的内存大小、堆大小,太大太小都不好。


我尝试使用netbeans profilers分析系统性能和内存,内存占用主要包括两块,一个是hibernate实体类二级缓存,大概有200M左右,另外是wicket用到的,不过这个工具也是第一次使用,不知道如何入门,我是看着这个文档做的(http://www.javaperformancetuning.com/tools/netbeansprofiler/)

wicket内存占用我是从wicket在磁盘中的session文件大小来推断的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics