【问题标题】:jar as daemon on ubuntu uses 100% cpujar 作为 ubuntu 上的守护进程使用 100% cpu
【发布时间】:2011-11-16 19:55:50
【问题描述】:

我启动一个 jar 文件作为守护进程。它是一个简单的扫描应用程序,运行一个扫描文件夹的线程。我使用 sleep 60000ms,所以如果我在我的 mac 上运行应用程序,cpu 使用率接近 0%。

如果我在我的 32b Ubuntu 服务器上将 jar 作为守护程序运行,它会在空闲时消耗 100% 的 cpu(例如,它扫描的文件夹中没有文件)。

sudo start-stop-daemon --start --quiet -b -m --pidfile /var/run/filecom.pid --exec /usr/bin/java -- -Xms128m -Xmx128m -jar /apps/FileCom/filecom.jar

我做错了什么?

谢谢

编辑

我做了一个 Thread.sleep(60000)。当我不将它作为守护进程运行时,它不会消耗那么多 CPU。我的猜测是它与我的守护进程有关。

public void run() 
{
    //Create our root folder (folder to scan)
    File root = new File(rootFolder);

    //Start the loop
    while(true)
    {
        //List all files in the root folder
        File[] filesInRoot = root.listFiles();

        Arrays.sort( filesInRoot, new Comparator<Object>()
        {
            public int compare(Object o1, Object o2) 
            {
                if (((File)o1).lastModified() < ((File)o2).lastModified()) 
                {
                    return -1;
                } 
                else if (((File)o1).lastModified() > ((File)o2).lastModified()) 
                {
                    return +1;
                } 
                else 
                {
                    return 0;
                }
                }

        }); 

        //If there are no files in the target folder then move the first file in the array
        if(filesInRoot.length>0)
        {

            LogUtil.write(">> Finds file in in queue: " + filesInRoot[0].getName());

            //Check that the file has been written, EOF
            if(checkEOF(filesInRoot[0]))
            {
                LogUtil.write(">> File is complete, preparing to move");
                    //Rename the file using time and date - to make it unique
                    Calendar cal = Calendar.getInstance();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                    Long time = cal.getTimeInMillis();
                    String fileprefix = sdf.format(cal.getTime())+time.toString();
                    String processFileName = fileprefix+"_"+filesInRoot[0].getName();
                    //Move the file and rename it
                    File processFile = new File(processFolder, processFileName);

                    boolean success = filesInRoot[0].renameTo(processFile);

                    if (success) 
                    {
                        LogUtil.write(">> Success: File was moved to "+processFolder);
                        LogUtil.write(">> Processing....");


                        try 
                        {   
                            //Do stuff

                         } 
                         catch (Exception e) //Handles all errors
                         {

                            LogUtil.write(e);
                         }
                         finally
                         {
                            //Create backup of the infile (outfile is bupped in writeResponseObject)
                            File bupInFile = new File(bupFolder+"/in", processFileName);
                            processFile.renameTo(bupInFile);
                            LogUtil.write(">> inFile backed up: "+bupInFile.getAbsolutePath());
                         }
                     }   
                     else
                     {
                         LogUtil.write(">> Failure: File could not be moved ");
                     }
                }
            else
            {
                LogUtil.write(">> Failure: file is still beeing written...");
            }
                try 
                {
                    Thread.sleep(FileCom.PROSchedule);
                } 
                catch (InterruptedException ie) 
                {
                    ie.printStackTrace();
                }
            }

    }

【问题讨论】:

    标签: java ubuntu jar cpu daemon


    【解决方案1】:

    查看代码,大括号不太匹配,看起来只有文件夹中有文件时您才在睡觉。

    在文件夹中的文件中尝试您的守护程序代码,看看 CPU 使用率是否仍然飙升。

    此外,如果您在代码中使用适当的缩进也会有所帮助。

    【讨论】:

    • 我自己开香蕉!我怎么能错过呢?!正如您所说,睡眠不在 while 循环的根目录中!谢谢!
    【解决方案2】:

    首先,如果您发布实际执行文件夹扫描的代码会有所帮助。这些 API 在每个操作系统的 VM 中都有非常不同的实现,因此您遇到不同的行为并不罕见。

    其次,您的代码是否是一个连续的 while 循环,没有任何线程在 Java 中完成休眠?如果是这样,这不是很好。你应该给你的代码睡眠/屈服时间,你应该在 Java 中而不是在命令行中这样做,这样 VM 将正确地处理操作系统调度程序以进行线程调度等。

    无论如何,您在 OS/X 上获得更好的 CPU 使用率的原因可能与该操作系统的激进抢占性有关,它不会让任何没有做任何“有用”的事情占用 CPU。

    【讨论】:

      【解决方案3】:

      --- 发布代码后编辑 ---

      你的问题出在这行代码块

          if(filesInRoot.length>0) {
                  ... a lot of stuff goes here ...
                  try 
                  {
                      Thread.sleep(FileCom.PROSchedule);
                  } 
                  catch (InterruptedException ie) 
                  {
                      ie.printStackTrace();
                  }
          }
      

      所以如果filesInRoot.length == 0你不睡觉。

      你需要像这样重新排列代码

          if (filesInRoot.length > 0) {
            ... a lot of stuff goes here ...
          }
      
          try {
            Thread.sleep(FileCom.PROSchedule);
          } catch (InterruptedException ie) {
            ie.printStackTrace();
          }
      

      --- 原帖如下---

      也许你做了一个对 MacOSX 有效但在 Ubuntu 中失败的假设。谁知道呢,您可能会使用 100% 的 CPU,因为您从未输入您的 sleep(...) 所在的代码块。

      源代码非常适合就此类主题进行相关讨论。没有它,一切都变成了猜谜游戏。我们很多人都擅长猜测,但我们不喜欢这样做。这太容易出错了,我们希望保持至少尝试提供有用帮助的声誉。

      尝试将相关代码放在一个非常小的示例程序中。充其量,您会在完成示例之前发现并解决您自己的问题。在最坏的情况下,您将有一个不同行为的工作示例,这将允许其他人为您提供有意义的相关解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-07
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 2011-07-21
        • 1970-01-01
        • 2023-03-02
        相关资源
        最近更新 更多