Session 拾遗与性能优化

这一切的原由要由 java.lang.OutOfMemoryError: PermGen space
说起,今天测试本地项目,惊呆了,永久代溢出,虽然没有再现 bug,
初步估计是加载项目太多或者某个项目下 jar 包过多导致的。

中途看到了这篇文章
产生了一些疑问

1<%@page session="false"%> 具体有什么用?
2session 究竟在哪个时间点被创建 ( 别回答客户端访问服务端时被创建)?

方便起见,答案在本文末尾,会的同学可以直接关闭,节约时间哦

翻阅了大量资料后,终于有了个全面的认知,基础的就不介绍了,直接说重点

  • 关闭浏览器是不会导致 session 被清除的,为什么常识上来看关闭浏览器后重新打开,像是 session 被清除了一样?
    只是原来的 session 对象丢失,新建了新的 session 对象,而 session 本身是一个 map 对象,所以当访问极大时,
    会创建大量 session 对象,导致内存溢出
  • session 是如何创建的呢?当服务端调用 HttpServletRequest.getSession(true) 才会被创建 设置为 false 时
    存在则返回 session 对象,不存在则返回 null。这时聪明的小伙伴应该会有和我一样的直觉,我的代码中即使没用 session 啊,但是
    凭借经验与印象,session 难道就不会创建吗?
    答案当然和我想的一样是否定的,此时 session 依旧会被创建,为什么呢?这就要从 JSP 原理说起了
    jsp 运行时,先会转换成一个 java 文件然后再编译成 class 文件,最后输出结果
    而正是在这个过程中,JSP 文件在转成 Servlet 时将会自动加上这样一条语句
    HttpSession session = HttpServletRequest.getSession(true) 而创建 session
    除非在 JSP 文件中显示的使用 <%@page session=”false”%> 关闭 session,默认为 true
    终于问题解决了!

    有兴趣的可以实现 HttpSessionListener 进行测试
    %TOMCAT_HOME%\work\Catalina\localhost\ jsp 编译后存放位置

总结与拓展

  • true 值(默认)表示,如果存在已有会话,则预定义变量 session (类型为 HttpSession)应该绑定到现有的会话;否则,创建新的会话并将其绑定到 session。false 值表示不自动创建会话,在 JSP 页面转换成 servlet 时,对变量 session 的访问会导致错误。
    对于高流量的网站,使用 session="false" 可以节省大量的服务器内存。但要注意,session="false" 并不禁用会话跟踪,它只是阻止 JSP 页面为那些尚不拥有会话的用户创建新的会话。由于会话是针对用户,不是针对贞面,所以,关闭某个页面的会话跟踪没有任何益处,除非有可能在同一客户会话中访问到的相关页面都关闭会话跟踪。

  • 既然了解了 session 的创建时机,学以致用,对于 性能的优化
    可以把网站的首页加上 session=false 这样可以就不会为自动为每位访问首页的用户都创建一个 session
    因为首页的访问量是很大的,可能很大一部分用户点开首页后不会进行下一步浏览,可能看一下概要就关了
    这样我们完全没有必要为他创建 session,延迟 session 的创建时机,可以避免创建不必要的对象
    缓解服务器内存压力,提高性能。

简要答案

本来是没必要写的,但想到有的同学(比如我),可能喜欢直接拉到下面来看答案,确认一下自己理解,就附一下啦! 很人性化吧!
session 是在访问 jsp 时默认创建的,session=false 可以让访问到 jsp 时不默认创建