`

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

阅读更多
本来是在新闻里的,不过觉得那里不合适讨论这种问题,所以另外开了一个新的帖子

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三个框架是首选,三个框架都有异曲同工之妙。
分享到:
评论
16 楼 greateWei 2010-03-28  
在此总结一下wicket学习使用的一些心得体会
1.使用dataprovider+detachabledatamodel组合模式,主要的好处:可以减少Page/Panel等组件代码整洁,数据提供和展示各司其职;提高代码重用;解决wicket session过大导致访问量上去后内存溢出问题;这一点在wicket官方文档中强调不过,初学入门时往往为了少写一些代码直接使用ListView+List方式;
2.当page或者page部分代码行数较多时,考虑是否可以抽取代码来组件新的对象;一般常用的是Panel扩展;提高代码重用;
3.经常关注wicket nabble论坛,空的时候看看别人的讨论,会有受益;
15 楼 greateWei 2009-10-05  
纠正之前对wicket 内存溢出的怀疑:

结合大家上述提出的一些内存占用分析工具,并都tomcat下临时session文件分析得出的,经过近两个月的调试和跟踪发现,内存溢出不是主要因为wicket session 内存占用引起的,是由于使用hibernate 查询缓存导致的。

通过程序调优,并将系统运行环境迁移到linux中,性能有很大提高。

不过wicket back和foward按钮问题还没找到好的解决办法。



14 楼 wl95421 2009-08-17  
profiler这种工具只能用来检测大的瓶颈点
至少小的点,基本用处不大,而且经常误导。
我仍然建议先用DiskSessionStore进行分析,检测哪一个页面占用空间过大。

另外不得不说,Wicket的stateless做得确实不好。
如果是我做,可能会提供一个stateless页面,然后强迫在某个方法中加载控件或者模型。
不过现在主要方向不是wicket,所以也没有时间再开发一些额外的功能了。
13 楼 greateWei 2009-08-15  
基本确定是wicket消耗过多内存引起的问题,主要是session文件过大,我将占用内存比较多的几个页面setVersioned(false),内存占用明显降低了,主要原因应该是编码时有些事项没考虑到,还不清楚,正查找
12 楼 bohemia 2009-08-15  
我觉得可以首先确认下问题本身是属于"内存泄露",还是"线程过多导致内存使用过多".
两者都会在一定程度之后,导致JVM崩溃.

上面提到的netbeansprofiler,瞄了一眼.好像没能看出什么问题来.
建议你的解决步骤:
1.(JDK1.4.2_19,或参照http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions)
JAVA_OPTIONS,添加
-XX:HeapDumpPath=./java_pid.hprof
-XX:+HeapDumpOnOutOfMemoryError

2.LoadRunner压力一下,按照你说的情况,很容易出现JVM崩溃,出错之后,生成hprof文件

3.使用工具分析下出现哪里的代码导致了崩溃.
可以分析到具体的类,具体的方法,同样也可以找到对象的大小等等关系
我用过的工具连接:
https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/webcontent/uuid/8070021f-5af6-2910-5688-bde8f4fadf31
分析的一篇参考文章:
https://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/6856

4.后续.
任何系统都会有最大容量限制
后续可以根据最大在线用户添加系统限制.防止系统过载.
另外,就是代码内存使用的优化了.

11 楼 魔力猫咪 2009-08-15  
我的建议是当溢出的时候把JVM的堆快照抓下来,然后用分析工具进行分析。
10 楼 greateWei 2009-08-15  
魔力猫咪 写道
请问你们遇到溢出的时候,有对JVM内存使用情况进行分析吗?不会是别处的内存泄漏吧!建议把内存快照拿下来进行分析,不然很难确定是什么东西造成的泄漏。
优化很重要,必须确定合适的内存大小、堆大小,太大太小都不好。


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

wicket内存占用我是从wicket在磁盘中的session文件大小来推断的
9 楼 greateWei 2009-08-15  
魔力猫咪 写道
请问你们遇到溢出的时候,有对JVM内存使用情况进行分析吗?不会是别处的内存泄漏吧!建议把内存快照拿下来进行分析,不然很难确定是什么东西造成的泄漏。
优化很重要,必须确定合适的内存大小、堆大小,太大太小都不好。


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

wicket内存占用我是从wicket在磁盘中的session文件大小来推断的
8 楼 魔力猫咪 2009-08-15  
请问你们遇到溢出的时候,有对JVM内存使用情况进行分析吗?不会是别处的内存泄漏吧!建议把内存快照拿下来进行分析,不然很难确定是什么东西造成的泄漏。
优化很重要,必须确定合适的内存大小、堆大小,太大太小都不好。
7 楼 greateWei 2009-08-15  
另外,其实很多场景都不需要将页面保存到session中,但如果使用了一些stateful控件,很多页面wicket都默认写入session了,不知不觉整个session文件就非常大了。
6 楼 greateWei 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的功能都无法使用了。

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




5 楼 wl95421 2009-08-14  
我虽然觉得Wicket非常地好,适合快速开发。
但对于技术能力不强的公司,我倒是不推荐,因为其实里面隐藏了很多陷井。
想把stateful的内容用好,并不是一件简单的事情。

至于如何判断某个对象序列化后的对象很大,其实可以继承DiskSessionStore,然后在序列化的时候,检查一下哪一个对象的字节数组太大,就很容易定位了。
如果懒地话,直接改一个DiskSessionStore的代码也就是了。
4 楼 greateWei 2009-08-14  
原来的这部分内容有误导观众嫌疑,我先移除吧,下次清楚了,再补充,~
3 楼 greateWei 2009-08-13  
引用
可以使用各种方式,如Profile,或者用DiskSessionStore来序列化Page,找到内存占用点,然后改正,比如说用Stateless控件。


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

看了一下磁盘中的session持久文件,发现有20来个session文件大小有10m左右,但是看了看代码,基本上都是遵守上述规则的,不知如何来定位wicket的内存占用点呢?从session文件来看,好像发现不了什么问题。
2 楼 greateWei 2009-08-07  
<div class="quote_title">wl95421 写道</div>
<div class="quote_div">
<p><strong>我给几个建议,可以结合用:</strong></p>
<ol>
<li>1500人呢,不算太小,当然也远不算大,用台64位的PC服务器,JVM上到3-4G内存,应该问题就能解决了。</li>
<li>Terracotta我不建议你使用,它的优势并非体现在这种不大不小规模的系统上,反而带入不必要的复杂度。</li>
<li>可以使用各种方式,如Profile,或者用DiskSessionStore来序列化Page,找到内存占用点,然后改正,比如说用Stateless控件。</li>
<li>序列化改良机制是一个不错的思路,但有一些技术风险,还是建议好好研究如何高效使用DiskSessionStore可能更合适。</li>
<li>我不知道你们的LoadModel是如何用地,我用得时候,是LoadModel中只放置一个Key值,然后用的时候通过Key值去数据库或者其它地方取,至于数据源则用它自己的缓存。</li>
</ol>
<p> </p>
<p>另外说每个页面如果是300K的话,我觉得肯定是有问题,比我假设的100K还要大上很多,也就难怪1500人会内存溢出了,还是建议多用LoadModel和Stateless控件。</p>
</div>
<p> </p>
<ol>
<li>编码中,现在确实按第5点来实现的。使用了一段时间后的感想:wicket的loadModel使用起来编码工作量比较大,而且一般用户使用wicket可能往往直接使用普通model方式来实现,wicket团队似乎应该在文档中强调这一点;</li>
<li>300K指的一个用户session磁盘中保存的文件大小,而不是一个页面的session大小;</li>
<li>如果JVM内存使用大小可以调整到3-4G,这个问题应该不大;我现在使用windows xp 32位,tomcat内存最大只能设置到1G;</li>
</ol>
<p>wicket使用了一段时间后,感觉wicket和hibernate有一个共同点:</p>
<ol>
<li>需要在开发使用过程中,不断做性能调优;</li>
<li>细节往往会决定性能:如控件对象增加final关键字就会session持久化,而这一般不会注意;<br>
</li>
<li>wicket的论坛非常友善,一般提交的问题第二天就有答案;常见的使用问题在论坛上找一找基本上能够解决的;</li>
</ol>
<p> </p>
<p> </p>
1 楼 wl95421 2009-08-07  
<p><strong>我给几个建议,可以结合用:</strong></p>
<ol>
<li>1500人呢,不算太小,当然也远不算大,用台64位的PC服务器,JVM上到3-4G内存,应该问题就能解决了。</li>
<li>Terracotta我不建议你使用,它的优势并非体现在这种不大不小规模的系统上,反而带入不必要的复杂度。</li>
<li>可以使用各种方式,如Profile,或者用DiskSessionStore来序列化Page,找到内存占用点,然后改正,比如说用Stateless控件。</li>
<li>序列化改良机制是一个不错的思路,但有一些技术风险,还是建议好好研究如何高效使用DiskSessionStore可能更合适。</li>
<li>我不知道你们的LoadModel是如何用地,我用得时候,是LoadModel中只放置一个Key值,然后用的时候通过Key值去数据库或者其它地方取,至于数据源则用它自己的缓存。</li>
</ol>
<p> </p>
<p>另外说每个页面如果是300K的话,我觉得肯定是有问题,比我假设的100K还要大上很多,也就难怪1500人会内存溢出了,还是建议多用LoadModel和Stateless控件。</p>

相关推荐

    wicket开发指南 pdf

    Wicket使用HTML作为页面模板,开发者可以在HTML中直接嵌入Java代码,创建动态的Web页面。每个HTML文件都可以对应一个或多个页面类,页面类负责处理页面的行为和逻辑。 **五、状态管理** Wicket是一个无状态的框架,...

    wicket开发指南

    本开发指南将带你深入了解Wicket的核心概念、架构以及如何有效地使用它进行开发。 ### 1. Wicket简介 Wicket 的核心理念是组件化,它将HTML页面与Java对象紧密关联,每个HTML元素都有对应的Java对象,这种绑定使得...

    Wicket.pdf(Wicket开发指南)

    ### Wicket 开发指南知识点概览 #### 一、Wicket 框架介绍 - **框架起源与发展:** - Wicket 是一种基于 Java 的 Web 应用框架,最初由 Marc Guillemot 和 Eelco Hillenius 开发。 - 该框架首次公开发布是在 ...

    Wicket开发指南

    **Wicket开发指南** Wicket框架是一个基于Java的开源Web应用程序框架,它的设计目标是提供一种简单、声明式和组件化的编程模型,让开发者能够更高效地构建动态、交互式的Web应用。Wicket的核心理念是将UI逻辑与HTML...

    wicket例子和开发指南

    Wicket是一个开源的Java Web应用程序框架,它提供了一种组件化的开发方式,...通过阅读开发指南并亲手运行这些示例,你将能够深入理解Wicket的工作原理,熟练掌握其开发技巧,从而在实际项目中更高效地使用Wicket框架。

    Wicket开发指南-简体版

    **2.2 使用Eclipse开发Wicket程序** - **安装Eclipse开发环境**:确保Eclipse环境中包含了必要的插件和支持。 - **配置Eclipse开发Wicket的环境**:设置项目依赖、构建路径等信息,确保开发环境正确无误。 #### 三...

    Wicket 1.4 开发手记(一) helloworld与环境配置

    ### Wicket 1.4 开发手记:Hello World与环境配置 #### 一、引言 在《Wicket 1.4 开发手记》系列的第一篇文章中,作者Steel.Ma分享了他对Wicket框架的一些见解,特别是针对Wicket 1.4版本的入门级介绍。文章首先对...

    Wicket1.40.war包+开发指南.rar

    3. **强类型**:Wicket使用Java的强大类型系统,这意味着开发者可以在编译时发现错误,而不是在运行时。 4. **分离关注点**:Wicket支持MVC模式,允许开发者清晰地分离业务逻辑、表示层和数据绑定。`Wicket开发指南...

    Wicket 8.X开发文档(中文翻译+英文原版)

    24.使用Wicket和Spring测试驱动开发 24.1。配置运行时环境 24.2。配置基于JUnit的集成测试环境 24.3。摘要 25. Wicket最佳实践 25.1。正确封装组件 25.2。将模型和页面数据放在字段中 25.3。正确命名Wicket ID 25.4...

    Wicket 开发指南

    - **URL到页面映射(URL to Page Mapping)**:Wicket使用基于类的URL映射,使得URL更加语义化。 4. **开发流程** - **创建页面**:定义一个继承自`org.apache.wicket.Page`的类,并在其中添加组件。 - **组件...

Global site tag (gtag.js) - Google Analytics