代码之家  ›  专栏  ›  技术社区  ›  Ciaran Archer

ColdFusion 9-我的线程占用了内存-如何阻止它?

  •  1
  • Ciaran Archer  · 技术社区  · 16 年前

    当CF9应用程序启动时,我有一个特定的线程。它管理一个队列并从队列中提取项目来处理它们。如果没有要从队列中提取的项目,它将 sleep() . 这个线程可以生存数周,处理和睡眠等。

    我遇到的问题是,我从队列中获取的项目在我处理完之后很长一段时间都保留在堆中(看起来像旧一代的项目)。

    JVM大约每小时进行一次完整的垃圾收集(我可以从jConsole中看出这一点),即使在jConsole运行时,我处理的项仍然保留在堆中。我能说出来是因为我做了一个 jmap 堆转储并使用内存分析工具Eclipse插件对其进行分析。

    Application.cfc

    <!--- Kick off a new thread and run through the queue --->
    <cfthread action="run" name="myThread">
    
        <cfloop condition="APPLICATION.threadProcessing eq true">
    
            <cfif APPLICATION.myQueue.hasNext()>
    
                <!--- Get next item --->
                <cfset tmpItem = APPLICATION.myQueue.next() />
    
                <!--- Ask item to process itself --->
                <cfset tmpItem.process() />
    
                <!--- PROBLEM: these 'tmpItem' objects are never cleaned up by the garbage collector! ---> 
    
                <!--- Then we sleep for an interval - this is to stop us hogging server resources --->
                <cfset sleep(2000) />
    
    
            <cfelse>
    
                <!--- Nothing in the queue, so sleep for a while... --->
                <cfset sleep(10000) />
    
            </cfif>
    
        </cfloop>   
    
    </cfthread>
    

    有人能告诉我是不是用错了范围什么的吗?有没有办法强制清理我的临时对象?我假设调用显式垃圾回收不会起作用,因为它无论如何都不会被清理。

    谢谢,西亚兰。

    4 回复  |  直到 16 年前
        1
  •  2
  •   Ben Doom    16 年前

    我可以提供两条建议。一个很可疑,但另一个很可靠。

    如果是我,我会调查的是一个预定的任务。它不会经常运行(我认为最短等待时间是1分钟,IIRC),但应该在任务终止时释放调用使用的所有内存。基本上,您只需删除外部循环和sleep(),并以普通调用的方式调用页面。我不完全确定您的队列是如何工作的,但由于它在应用程序范围内,只要您的任务在应用程序树中(或包含该应用程序文件),您就应该仍然能够访问它。

    根据你的其他评论,听起来这不是一个共享的环境。是否有其他障碍阻碍您运行计划任务?

        2
  •  0
  •   Joel    16 年前

    如果我想弄清这一点,我想知道是什么阻止这些对象成为gc的,我会使用 hprof 和 HAT

    内存gc问题的另一个原因是重写对象,尽管听起来它不适用于您的情况对象.finalize(). 这是 because 在回收它们之前,它们必须由终结器线程处理,如果它们的创建速度比终结器线程处理它们的速度快,则可能会遇到内存问题。

        3
  •  0
  •   jim collins    12 年前

    我的理解是线程使用堆栈,而不是堆,因此线程内部没有“垃圾收集”。它们被保留在堆中,因为它们仍然在堆栈中。如果我错了,谁来纠正我。

        4
  •  -2
  •   Aaron Greenlee    16 年前

    您可能需要研究如何锁定应用程序范围的使用。