Tomcat StandardSession 内存泄露怎么解决

a15089415104 2019-10-12 05:44:26
加精
最近开发一个项目,内存不断的增大,通过jmap等工具发现 StandardSession这个类的实例有140万个。通过可视化工具可以发现每个 StandardSession其实都应该做过期处理的,但是就是没有被回收。

这个解决的思路是什么,有大佬可以指点一下不

jmap实例图



某个 StandardSession 实例对象的值


代码中只有在过滤器中用到了


ps:
在过滤器中会重新设置该session对象的过期时间为18000秒(即5个小时),这里不管是30分钟还是5个小时,其实都不会出现内存泄露

使用框架
springboot:2.1.0.RELEASE

内置的tomcat版本 9.0.12
...全文
2859 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
5、6 是混分的吗?
qq_34219439 2020-02-25
  • 打赏
  • 举报
回复
支持楼主学习老师,支持
小杨互联网 2019-10-31
  • 打赏
  • 举报
回复
配置一下jvm不就好啦吗?通过java -jar 这里写jvm参数
grt20091028 2019-10-15
  • 打赏
  • 举报
回复
MinHeapFreeRatio 参数用来设置堆空间最小空闲比例,默认值是 40。当堆空间的空闲内存小于这个数值时,JVM 便会扩展堆空间。

MaxHeapFreeRatio 参数用来设置堆空间最大空闲比例,默认值是 70。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆。


这个好
Andrew Barker 2019-10-15
  • 打赏
  • 举报
回复
MinHeapFreeRatio 参数用来设置堆空间最小空闲比例,默认值是 40。当堆空间的空闲内存小于这个数值时,JVM 便会扩展堆空间。

MaxHeapFreeRatio 参数用来设置堆空间最大空闲比例,默认值是 70。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆

我也觉得这个不错
a15089415104 2019-10-14
  • 打赏
  • 举报
回复
引用 1 楼 oh_Maxy 的回复:
好奇你们是怎么拿到StandardSession的,有没有在什么别的地方持有这个对象未释放,或者是否有并发访问的情况。
找到原因了,并不是内存泄露,尴尬。 该web应用内存占用过高的问题是使用了稳定堆。 部分的堆信息

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 3287285760 (3135.0MB)
   used     = 53116712 (50.656044006347656MB)
   free     = 3234169048 (3084.3439559936523MB)
   1.6158227753220944% used
MinHeapFreeRatio 参数用来设置堆空间最小空闲比例,默认值是 40。当堆空间的空闲内存小于这个数值时,JVM 便会扩展堆空间。 MaxHeapFreeRatio 参数用来设置堆空间最大空闲比例,默认值是 70。当堆空间的空闲内存大于这个数值时,便会压缩堆空间,得到一个较小的堆。 可以看到项目中最小空闲比例为0,最大空闲比例为100,这表示堆只会增长,不会缩减。 项目中有时候访问量非常大,这时候不断的增加 Eden堆 的大小,但是当该应用访问量降下来后,此时 Eden使用率是很低的。 上面可以看到Eden 总大小为3.1G,但是只使用了50M,Eden 使用率为1.6。由于使用稳定堆的原因,虽然Eden使用率很低,但JVM并不会释放空闲内存,导致项目就算在访问量不大的时候,还是占用非常多的内存。 此贴终结。
长乐smile 2021-11-13
  • 举报
回复
@a15089415104 请问最后是怎么解决的?
a15089415104 2019-10-14
  • 打赏
  • 举报
回复
引用 1 楼 oh_Maxy 的回复:
好奇你们是怎么拿到StandardSession的,有没有在什么别的地方持有这个对象未释放,或者是否有并发访问的情况。
只有在拦截器上用到 拦截器函数 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { HttpSession httpSession = request.getSession(); //调用设置session函数 setSession(httpSession, uin, channelId); } 有一个比较奇怪的现象是我本地测试的话,这些httpSession过期会被清除的,但是线上的就不行了,可能是线上的访问量比较大
oh_Maxy 2019-10-12
  • 打赏
  • 举报
回复
好奇你们是怎么拿到StandardSession的,有没有在什么别的地方持有这个对象未释放,或者是否有并发访问的情况。

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧