我们遇到异常高的内存使用问题。我观察到我们代码中的许多地方都是从DB中提取100条记录,将其打包在自定义数据对象中,将其添加到arraylist并存储在会话中。我想知道在会话中存储数据的建议上限是多少。只是一个好习惯不好的做法。
我正在使用JRockit 1.5和1.6GB的RAM。我使用Jprobe进行了分析,发现应用程序的某些部分内存占用非常大。大部分数据正在进入会话中以供日后使用。
答案 0 :(得分:6)
如果要在会话中存储数据以提高性能,请考虑使用真正的缓存,因为缓存是应用程序范围的,而会话是按用户进行的,这会导致不必要的重复其他类似的对象。
但是,如果您要存储它们以供用户编辑此对象(我怀疑,因为数百个对象太多了),请尝试最小化存储的数据量或研究乐观并发控制。
答案 1 :(得分:6)
这完全取决于通常会出现多少会话(这又取决于您拥有多少用户,他们在网站上停留多长时间以及会话超时)以及您的服务器具有多少RAM。
但首先:您是否真的使用内存分析器告诉您“高内存使用率”是由会话数据引起的,还是只是猜测?
如果您遇到的唯一问题是生产机器上的“高内存使用率”(即它可以处理生产负载,但效果不如您所愿),最简单的解决方案是获得更多内存服务器 - 比重新设计应用程序更快,更便宜。
但是,在会话中缓存整个结果集也有不同的原因:如果数据库中的数据发生更改而用户希望看到更改,该怎么办?如果您要缓存,请使用在数据库请求级别执行此操作的one of the existing systems - 它们将允许您在用户之间缓存结果,并且它们具有缓存失效的功能。
答案 2 :(得分:1)
我会说这在很大程度上取决于您期望的活动会话数。如果您正在使用<编写Intranet应用程序20个用户,在会话中放几MB肯定没问题。但是,如果你期望5000个实时会话,每个会话存储的每MB数据占5GB RAM。
但是,我通常建议不要在会话中存储来自DB的任何数据。只需从DB获取每个请求。如果性能是个问题,请使用应用程序范围的缓存(例如Hibernate的二级缓存)。
答案 3 :(得分:1)
它的种数据是什么?它是真的需要每个会话还是可以在应用程序级别缓存?你真的需要所有的列还是只需要一个子集?它被访问的频率是多少?需要提供哪些页面?等等。
在您真正需要时从数据库中检索记录可能更有意义。在会话中存储数百条记录绝不是一个好策略。
答案 4 :(得分:1)
我想尝试存储足以在后续请求中重新创建必要环境的最小数据量。如果您要在内存中存储以避免数据库往返,那么真正的缓存解决方案(如Memcache)可能会有所帮助。
如果您将这些会话存储在内存而不是数据库中,则会保存往返,只要内存负载较低,并且没有分页,就会更快地提供请求。一旦客户端数量增加并且分页开始,大多数客户端的响应时间将大幅减少。这两个变量都是反向相关的。
更好地衡量数据库服务器的延迟,这在大多数情况下通常足够低,被认为是一种可行的存储方式,而非内存。
答案 5 :(得分:1)
尝试将当前存储在会话中的数据拆分为用户特定的静态数据。然后实现所有静态部分的缓存。这将在应用程序范围内为您提供大量重用,并且仍然允许您缓存用户正在处理的特定数据。
答案 6 :(得分:1)
您还可以创建每个用户的迷你sqlite数据库并连接到它,并存储用户正在其中访问的数据,然后只需从用户请求它时检索记录,并在用户断开连接之后删除sqlite数据库。