【问题标题】:Java program doesn't close after cronjob callcronjob 调用后 Java 程序不关闭
【发布时间】:2012-09-11 19:20:33
【问题描述】:

我编写了一个从我的邮件帐户中检索邮件的 Java 程序。

Ubuntu 服务器上的 cronjob 每 15 分钟调用一次此 jar。

定时任务:

/bin/sh /root/scripte/cron_bugtracker.sh

cron_bugtracker.sh:

java -jar /path/to/file.jar

jar 工作正常,但程序不退出。

当我执行ps ax | grep java 时,它总是以java -jar /path/to/file.jar 作为命令显示很多java 进程:

32208 ? Sl 0:59 java -jar /path/to/file.jar

我的 Java 程序是这样工作的:

  1. 我主要调用构造函数
  2. 在构造函数中,我使用 javax.mail 调用获取邮件的方法。*
  3. 那么程序就完成了……至少应该是

有谁知道为什么程序不退出?请帮忙。

编辑:

在日志文件中我发现了这个:

“Control”是我的主类的名称。

Full thread dump Java HotSpot(TM) Client VM (23.1-b03 mixed mode):

"Service Thread" daemon prio=10 tid=0xb76bd000 nid=0x292 runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread0" daemon prio=10 tid=0xb76bb400 nid=0x291 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0xb76b9800 nid=0x290 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0xb7681c00 nid=0x28f in Object.wait() [0xa10ad000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0xa1585650> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        - locked <0xa1585650> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(Unknown Source)
        at java.lang.ref.Finalizer$FinalizerThread.run(Unknown Source)

"Reference Handler" daemon prio=10 tid=0xb7680000 nid=0x28e in Object.wait() [0xa10fe000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0xa1585228> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:503)
        at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source)
        - locked <0xa1585228> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0xb7606000 nid=0x28c runnable [0xb77ae000]
   java.lang.Thread.State: RUNNABLE

        at java.lang.ClassLoader.findBootstrapClass(Native Method)
        at java.lang.ClassLoader.findBootstrapClassOrNull(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        - locked <0xa1855398> (a java.lang.Object)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at com.sun.mail.pop3.POP3Folder.createMessage(POP3Folder.java:362)
        at com.sun.mail.pop3.POP3Folder.getMessage(POP3Folder.java:343)
        - locked <0xa18261a0> (a com.sun.mail.pop3.POP3Folder)
        at javax.mail.Folder.getMessages(Folder.java:947)
        - locked <0xa18261a0> (a com.sun.mail.pop3.POP3Folder)
        at javax.mail.Folder.search(Folder.java:1231)
        at Control.receive(Control.java:53)
        at Control.<init>(Control.java:29)
        at Control.main(Control.java:24)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

"VM Thread" prio=10 tid=0xb767a800 nid=0x28d runnable

"VM Periodic Task Thread" prio=10 tid=0xb76bf800 nid=0x293 waiting on condition

JNI global references: 163

Heap
 def new generation   total 4928K, used 2907K [0xa1580000, 0xa1ad0000, 0xa6ad0000)
  eden space 4416K,  65% used [0xa1580000, 0xa1856e20, 0xa19d0000)
  from space 512K,   0% used [0xa19d0000, 0xa19d0000, 0xa1a50000)
  to   space 512K,   0% used [0xa1a50000, 0xa1a50000, 0xa1ad0000)
 tenured generation   total 10944K, used 0K [0xa6ad0000, 0xa7580000, 0xb1580000)
   the space 10944K,   0% used [0xa6ad0000, 0xa6ad0000, 0xa6ad0200, 0xa7580000)
 compacting perm gen  total 12288K, used 2688K [0xb1580000, 0xb2180000, 0xb5580000)
   the space 12288K,  21% used [0xb1580000, 0xb1820230, 0xb1820400, 0xb2180000)
No shared spaces configured.

【问题讨论】:

  • 如果您可以继续隔离阻塞的代码...那就太好了,是的。
  • 或许可以进行一些登录,看看代码在哪里
  • 如果你自己启动你的java程序,它的行为是否符合预期?
  • 我认为他很清楚问题在哪里。他提到程序没有退出;他没有提到该程序没有做它应该做的事情。事实上,他说程序可以工作(“jar 工作正常,但程序没有退出”)。
  • @ilmiacs:如果我用 eclipse 启动它就可以了。

标签: java cron jakarta-mail


【解决方案1】:

执行线程转储以找出仍在运行的内容:如果您使用的是 Oracle JVM,则可以使用 jstack PID。

【讨论】:

  • +1 - 好主意!它完成了:$JAVA_HOME/bin/jstack -l [PID]&gt; dump.txt 然后kill -3 [PID]
  • jstack 或 kill -3。但是你需要进程的输出来获得 kill -3 的结果,而 jstack 在它自己的输出上打印线程转储。
  • 所以,很明显,你没有退出 main,甚至你的类的构造函数。
  • 这是唯一运行实例上的线程转储吗?我会在开始一个新实例之前杀死所有实例,以确保所涉及的 POP 服务器没有锁定。
  • +1 实际建议了一种直接处理挂起的方法。
【解决方案2】:

在程序的最后放置一个调试打印。 如果您看到打印,则表示主线程结束,但程序没有退出。我猜 JavaMail 有一个打开的线程(可能是一个邮件会话),需要关闭。您确定要在退出前关闭所有资源吗?

【讨论】:

  • 花了一段时间,但我发现(有很多 println 的)有时 session.getStore(); 和其他时候 store.getFolder("INBOX"); 挂断。我不知道如何正确解决问题。我写了一个 shell 脚本来杀死死进程。
  • 您是否尝试过执行线程转储,就像下面 Frank 建议的那样?可能已经为您节省了不少 println 的...
  • pastebin.com/JURtzUHv 我是否理解它与java.nio.file.Files.createTempFile() 有关?
【解决方案3】:

尝试在作业完成时显式使用 JVM 完成。这是执行此操作的代码:

System.exit(0);

正如 iccthedral 所说,可能有一些代码阻塞了你的程序。

【讨论】:

  • 否决,因为这会阻碍潜在的资源泄漏。我不会急于明确退出 JVM 作为未知挂起的解决方法。
  • +1 因为查看 OP 的假设是否正确会很有用,但 Isaac 是对的 - 它无助于检测问题的根源。一个好的答案是您的两个答案 (TMHO) 的组合。
  • 我认识伙计们。感谢您的建议!
猜你喜欢
  • 2017-04-26
  • 2013-12-22
  • 1970-01-01
  • 2011-03-26
  • 1970-01-01
  • 2011-03-08
  • 2019-04-27
  • 2012-06-30
  • 2014-02-09
相关资源
最近更新 更多