2012-05-22 20 views
10

में मेमोरी लीक को कैसे रोकें मैं अपने प्रोजेक्ट में क्वार्ट्ज का उपयोग कर रहा हूं। मेरे वेब अनुप्रयोग जाहिरा तौर पर एक स्मृति रिसाव का कारण बना है जब यह बंद हो जाता है, त्रुटि है:क्वार्ट्ज

SEVERE: A web application appears to have started a TimerThread named [Timer-12] via the java.util.Timer API but has failed to stop it. To prevent a memory leak, the timer (and hence the associated thread) has been forcibly cancelled. 
Jan 2, 2013 6:55:35 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads 
SEVERE: A web application appears to have started a thread named [DefaultQuartzScheduler_Worker-1] but has failed to stop it. This is very likely to create a memory leak. 

मैं org.quartz.ee.servlet.QuartzInitializerServlet और org.quartz.ee.servlet.QuartzInitializerListener इस्तेमाल किया। मेरे कारखाने के लिए कोड है:

StdSchedulerFactory factory = (StdSchedulerFactory) context.getAttribute(QuartzInitializerListener.QUARTZ_FACTORY_KEY); 

और क्वार्ट्ज के लिए सेटिंग्स web.xml में है:

<servlet> 
     <servlet-name> 
      QuartzInitializer 
     </servlet-name> 
     <display-name> 
      Quartz Initializer Servlet 
     </display-name> 
     <servlet-class> 
      org.quartz.ee.servlet.QuartzInitializerServlet 
     </servlet-class> 
     <load-on-startup> 
      1 
     </load-on-startup> 
     <init-param> 
      <param-name>shutdown-on-unload</param-name> 
      <param-value>true</param-value> 
     </init-param> 
     <init-param> 
      <param-name>wait-on-shutdown</param-name> 
      <param-value>true</param-value> 
     </init-param> 
     <init-param> 
      <param-name>start-scheduler-on-load</param-name> 
      <param-value>true</param-value> 
     </init-param> 
    </servlet> 
    <context-param> 
     <param-name>quartz:shutdown-on-unload</param-name> 
     <param-value>true</param-value> 
    </context-param> 
    <context-param> 
     <param-name>quartz:wait-on-shutdown</param-name> 
     <param-value>true</param-value> 
    </context-param> 
    <context-param> 
     <param-name>quartz:start-on-load</param-name> 
     <param-value>true</param-value> 
    </context-param> 
    <listener> 
     <listener-class> 
      org.quartz.ee.servlet.QuartzInitializerListener 
     </listener-class> 
    </listener> 

कृपया मुझे इस स्मृति रिसाव को हल करने में मदद !!

उत्तर

0

मुझे लगता है कि आप चाहते हैं: उपसर्ग जो क्वार्ट्ज कि विन्यास की स्थापना के लिए "गलत" का डिफ़ॉल्ट मान पर वापस लौटने के कारण हो सकता है:

 <init-param> 
     <param-name>wait-on-shutdown</param-name> 
     <param-value>true</param-value> 
    </init-param> 

आप एक "क्वार्ट्ज" है।

+0

नहीं, "क्वार्ट्ज:" उपसर्ग सही है। कृपया यहां जाएं: http: //quartz-scheduler.org/api/2.0.0/org/quartz/ee/servlet/QuartzInitializerListener.html। –

+0

आप गलत दस्तावेज पढ़ रहे हैं: आपका लिंक "श्रोता" के लिए है और आप "सर्वलेट" को कॉन्फ़िगर कर रहे हैं। किसी कारण से, वे वैसे ही व्यवहार नहीं करते हैं। देखें: http://quartz-scheduler.org/api/2.0.0/org/quartz/ee/servlet/QuartzInitializerServlet.html –

+0

यह सेटिंग org.quartz.ee.servlet.QuartzInitializerServlet और "quartz:" उपसर्ग के लिए है org.quartz.ee.servlet.QuartzInitializerListener के लिए। हालांकि, मैं "क्वार्ट्ज:" उपसर्ग हटाता हूं लेकिन स्मृति रिसाव को सही नहीं करता हूं। –

2

मैं देख रहा हूँ आपको दो में ... प्रारंभ - org.quartz.ee.servlet.QuartzInitializerServlet के माध्यम से पहली -

org.quartz.ee.servlet.QuartzInitializerListener

के माध्यम से दूसरे या तो हटाने QuartzInitializerServlet या QuartzInitializerListener (और वे पैरामीटर भी इसी) ... आप (विशिष्ट कारणों के लिए) अनेक उदाहरण सामने आना, (QuartzInitializerServlet साथ जाने के लिए और उदाहरण के प्रति विभिन्न उपयोग करने के लिए मत भूलना) org.quartz.InterruptableJob को लागू करने से

4

आप ठीक ढंग से धागे से शुरू हो रहा बाधित कर सकते हैं चाहते हैं सर्वलेट अनलोडिंग। अगर काम से पहले ही परेशान हो जाता है निष्पादित नहीं किया गया है

@DisallowConcurrentExecution 
public class Job implements InterruptableJob { 

    private Thread thread; 

    @Override 
    public void execute(JobExecutionContext context) throws JobExecutionException { 
     thread = Thread.currentThread(); 
     // ... do work 
    } 

    @Override 
    public void interrupt() throws UnableToInterruptJobException { 
     thread.interrupt(); 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      throw new UnableToInterruptJobException(e); 
     } finally { 
      // ... do cleanup 
     } 
    } 
} 

यह उदाहरण, धागा चर पर एक रेस स्थिति बग हो सकती है। मैं लक्षित आवेदन के जीवन चक्र के आधार पर सुझावों के लिए अंतिम समाधान खोलता हूं। यदि आपको एक ही नौकरी के उदाहरण के माध्यम से समवर्ती निष्पादन की आवश्यकता है, तो एकाधिक धागे को संभालने के लिए समाधान बढ़ाएं और @DisallowConcurrentExecution एनोटेशन को हटा दें।

क्वार्ट्ज संपत्ति org.quartz.scheduler.interruptJobsOnShutdownWithWait पर काम करने के लिए true पर सेट होना चाहिए। शेड्यूलर के लिए प्रॉपर्टी फ़ाइल को परिभाषित करके या वसंत ढांचे का उपयोग करते हुए बीन संदर्भों द्वारा इसे किया जा सकता है।

उदाहरण quartz.properties फ़ाइल:

org.quartz.scheduler.interruptJobsOnShutdownWithWait=true 

नोट कि रुकावट ही अगर अनुसूचक शटडाउन होने पर प्रतीक्षा करने के लिए, scheduler.shutdown(true) करने के लिए एक कॉल में कॉन्फ़िगर किया गया है भेजा जाता है।

0

आप अपने वेब अनुप्रयोग के लिए ServletContextListener इंटरफेस के अपने खुद के कार्यान्वयन का उपयोग कर रहे हैं, तो आप कर सकते हैं बंद क्वार्ट्ज contextDestroyed विधि में शान से। क्वार्ट्ज संस्करण 2.1.7 के लिए नमूना कोड के नीचे कृपया पाएं।

अपनी नौकरी:

import org.quartz.Job; 
import org.quartz.JobExecutionContext; 
import org.quartz.JobExecutionException; 

public class CronJob implements Job { 
    public void execute(JobExecutionContext context) 
      throws JobExecutionException { 
     // TODO: do you job 
    } 
} 

अपनी नौकरी अनुसूचक:

import org.quartz.CronScheduleBuilder; 
import org.quartz.JobBuilder; 
import org.quartz.JobDetail; 
import org.quartz.JobKey; 
import org.quartz.Scheduler; 
import org.quartz.SchedulerException; 
import org.quartz.Trigger; 
import org.quartz.TriggerBuilder; 
import org.quartz.impl.StdSchedulerFactory; 

public class CronJobScheduler { 

    private static CronJobScheduler instance = new CronJobScheduler(); 
    private Scheduler scheduler; 

    private CronJobScheduler() {  
     try { 
      scheduler = new StdSchedulerFactory().getScheduler(); 
     } catch (SchedulerException e) { 
      // TODO 
     } 
    } 

    public static CronJobTrigger getInstance() { 
     return instance; 
    } 

    public void trigger() { 
     JobKey jobKey = JobKey.jobKey("myJobName", "myJobGroup");  
     JobDetail job = JobBuilder.newJob(CronJob.class).withIdentity(jobKey).build(); 

     Trigger trigger = TriggerBuilder 
       .newTrigger() 
       .withIdentity("myTriggerName", "myJobGroup") 
       .withSchedule(CronScheduleBuilder.cronSchedule("0 0 1,13 * * ?")) 
       .build(); 

     try { 
      scheduler.start(); 
      scheduler.scheduleJob(job, trigger); 
     } catch (SchedulerException e) {  
      // TODO 
     } 
    } 

    public void shutdown(boolean waitForJobsToComplete) { 
     try { 
      scheduler.shutdown(waitForJobsToComplete); 
     } catch (SchedulerException e) { 
      // TODO 
     } 
    } 

} 

ServletContextListener इंटरफ़ेस का आपका कार्यान्वयन:

import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 

public class MyServletContextListener implements ServletContextListener { 

    @Override 
    public void contextDestroyed(ServletContextEvent arg0) { 
     CronJobScheduler.getInstance().shutdown(true); 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent arg0) { 
     CronJobScheduler.getInstance().trigger(); 
    } 

} 

आपका web.xml

<listener> 
    <listener-class>my.package.name.MyServletContextListener</listener-class> 
</listener> 
संबंधित मुद्दे