zoukankan      html  css  js  c++  java
  • SSH内存泄露及Spring Quartz问题

    问题的起因:


    为客户开发了一个系统权且称他为TM吧,用的是tomcat6+myelipse6+jdk1.6环境,框架用SSH。我调试完这个系统程序后,将此程序重新COPY了一份,改名叫TMT,但是发布的Web名还是叫TM。同样用同一个Tomcat来Run的。问题发生了,我在TMT项目里修改后,RUN起来运行的居然是TM项目中的代码。 
    尝试过删除TOMCAT6下的WORK目录下的缓存文件,也尝试过在TOMCAT的BIN目录下的Startup.bat中脚本头部加上一句: 
    rd /s /q TM 
    rd /s /q ..workCatalinalocalhostTM 
    ..incatalina start 
    还是没有用。 
        在TOMCAT6的conf目录下server.xml中添加: 
    <Context path="" docBase="" debug="0" reloadable="true" /> 
    也还是没有用。 


    在Tomcat的manage里也reload过了,都无法更新程序版本,运行都是之前TM项目中的代码,之后TMT项目里的代码链接的数据库和TM项目链接的数据库是不同的,将hibernate的执行sql的语句显示在Console界面中,发现数据库用的是TM项目中的数据库,可我运行的程序是TMT项目。无语了。。。。 


    尝试清除Eclipse的缓存,删除[eclipsehome]/configuration下除.settings子目录和config.ini文件外其它的子目录。 还是没有用,仍然调用是老的程序。
    最后尝试在myclipse的快捷方式启动是加入参数 -clean启动,还是无济于事。


    =======================================================


    接下来在javaeye中遍寻解决方案,无意中翻到Struts+Spring+Hibernate内存泄漏查找与处理一篇Robbin参与讨论的帖子,谈到使用org.springframework.web.util.IntrospectorCleanupListener监听器处理由 JavaBeans Introspector的使用而引起的缓冲泄露的问题,和Quartz定时调度比较理想的使用方式。以下节选部分内容供今后参考学习。


    =======================================================


    IntrospectorCleanupListener使用:


    "在服务器运行过程中,Spring不停的运行的计划任务和OpenSessionInViewFilter,使得Tomcat反复加载对象而产生框架并用时可能产生的内存泄漏,则使用IntrospectorCleanupListener作为相应的解决办法。" 


    引用: 


       spring中的提供了一个名为org.springframework.web.util.IntrospectorCleanupListener的监听器。它主要负责处理由 JavaBeans Introspector的使用而引起的缓冲泄露。spring中对它的描述如下:它是一个在web应用关闭的时候,清除JavaBeans Introspector的监听器.web.xml中注册这个listener.可以保证在web 应用关闭的时候释放与掉这个web  应用相关的class loader 和由它管理的类如果你使用了JavaBeans Introspector来分析应用中的类,Introspector 缓冲中会保留这些类的引用.结果在你的应用关闭的时候,这些类以及web 应用相关的class loader没有被垃圾回收.不幸的是,清除Introspector的唯一方式是刷新整个缓冲.这是因为我们没法判断哪些是属于你的应用的引用.所以删除被缓冲的introspection会导致把这台电脑上的所有应用的introspection都删掉.需要注意的是,spring 托管的bean不需要使用这个监听器.因为spring它自己的introspection所使用的缓冲在分析完一个类之后会被马上从javaBeans Introspector缓冲中清除掉.应用程序中的类从来不直接使用JavaBeans Introspector.所以他们一般不会导致内部查看资源泄露.但是一些类库和框架往往会产生这个问题.例如:Struts 和Quartz.单个的内部查看泄漏会导致整个的web应用的类加载器不能进行垃圾回收.在web应用关闭之后,你会看到此应用的所有静态类资源(例如单例).这个错误当然不是由这个类自  身引起的. 
    用法很简单,就是在web.xml中加入: 
        <listener> 
            <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> 
        </listener> 


    ======================================================= 


    Quartz问题: 


    引用Robbin原话: 


    对于Web容器来说,最忌讳应用程序私自启动线程,自行进行线程调度,像Quartz这种在web容器内部默认就自己启动了10线程进行异步job调度的框架本身就是很危险的事情,很容易造成servlet线程资源回收不掉。quartz还有一个问题就是不支持cluster。导致使用quartz的应用都没有办法做群集。 


    采取的办法就是自己单独启动一个Job Server,来跑job,不会部署在web容器中。其他web节点当需要启动异步任务的时候,可以通过种种方式(DB, JMS, Web Service, etc)通知Job Server,而Job Server收到这个通知之后,把异步任务加载到自己的任务队列中去。 
    其实想改造当前已经集成quartz的web应用也不算困难: 
    例如可以使用数据库的表来记录和维护任务队列和状态,把quartz部分完全从web应用中剥离出去,自己写一个Java Main程序把配置quartz的spring容器跑起来,这样Job Server就启动了(注意这个Job Server完全脱离tomcat)。此外这个Main程序应该再启动一个子线程,定期扫描数据库的任务队列表: 
    有新的任务就加入quartz的任务调度; 
    把当前任务的执行状态写入任务表; 
    看到删除任务的表字段状态以后,删除相应的任务。 
    然后web应用去掉quartz部分配置,把原来的调用quartz任务的代码改写为读写数据库的任务表,这样就把job部分完全从web容器剥离掉了,甚至web容器做cluster也没有问题了,并且多个web节点在同时读写任务表的时候,还有数据库的事务来确保操作的一致性,实在是很棒。 
    另外还可以单独做一个job管理界面,可以通过web界面手工添加任务,查看任务状态,删除任务等等。


  • 相关阅读:
    Springboot 之 自定义配置文件及读取配置文件
    SQLSERVER系统视图 sql server系统表详细说明
    MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
    使用Ecplise git commit时出现"There are no stages files"
    maven添加sqlserver的jdbc驱动包
    java将XML文档转换成json格式数据
    java将XML文档转换成json格式数据
    cannot be resolved. It is indirectly referenced from required .class files
    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2012-12-12 12:01:01': not a valid representation (error: Can not parse date "2012-12-
    @Autowired注解和静态方法 NoClassDefFoundError could not initialize class 静态类
  • 原文地址:https://www.cnblogs.com/ycpanda/p/3637303.html
Copyright © 2011-2022 走看看