Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java应用程序和AMD处理器问题_Java_Sockets_Intel_Serversocket - Fatal编程技术网

Java应用程序和AMD处理器问题

Java应用程序和AMD处理器问题,java,sockets,intel,serversocket,Java,Sockets,Intel,Serversocket,我们有一个windows应用程序,它在WindowsXP、7、8、8.1上进行了测试。应用程序由两部分组成:引导程序和主应用程序。引导确保主应用程序的更新,并在特定点更新主应用程序。但是用户可以通过任务管理器Ctrl+Shift+ESC->进程强制停止Boostrap进程,方法是杀死一个名为javaw的进程。在这种情况下,主应用程序将不会更新,旧版本将启动。为了避免这样的问题,我们通过套接字引入了引导程序和主应用程序的接口。以下是引导启动时的VM参数: javaw.exe-Xms75M-Xmx9

我们有一个windows应用程序,它在WindowsXP、7、8、8.1上进行了测试。应用程序由两部分组成:引导程序和主应用程序。引导确保主应用程序的更新,并在特定点更新主应用程序。但是用户可以通过任务管理器Ctrl+Shift+ESC->进程强制停止Boostrap进程,方法是杀死一个名为javaw的进程。在这种情况下,主应用程序将不会更新,旧版本将启动。为了避免这样的问题,我们通过套接字引入了引导程序和主应用程序的接口。以下是引导启动时的VM参数:

javaw.exe-Xms75M-Xmx90M-Xincgc-jar bootstrap.jar

引导程序中有一个SocketServer类:

public class Provider {
    ServerSocket providerSocket;
    Socket connection = null;
    ObjectOutputStream out;
    ObjectInputStream in;
    String message;

    public Provider() {
    }

    public void run() {
        try{
            providerSocket = new ServerSocket(54345);
            connection = providerSocket.accept();
            out = new ObjectOutputStream(connection.getOutputStream());
            out.flush();
            in = new ObjectInputStream(connection.getInputStream());
            sendMessage("Connection successful");
            do {
                try {
                    message = (String)in.readObject();
                    if (message.equals("bye")) {
                        sendMessage("bye");
                    }
                } catch(ClassNotFoundException cnfe) {
                    cnfe.printStackTrace();
                }
            } while (!message.equals("bye"));
        } catch(IOException ioe) {
            ioe.printStackTrace();
        } finally {
            try {
                in.close();
                out.close();
                providerSocket.close();
            } catch(IOException ioef) {
                ioef.printStackTrace();
            }
        }
    }

    public void sendMessage(String msg) {
        try {
            out.writeObject(msg);
            out.flush();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public void stop() {
        if (providerSocket != null && in != null && out != null && !providerSocket.isClosed()) {
            try {
                in.close();
                out.close();
                providerSocket.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
}
主应用程序是通过ProcessBuilder引导启动的,如下所示:

public static void communicate(Process process) {
    final BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.forName("Windows-1251")));
    final BufferedReader stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream(), Charset.forName("Windows-1251")));
    //InputStream
    new Thread() {
        @Override
        public void run() {
            String line;
            try {
                while ((line = stdOut.readLine()) != null) {
                    debugOut(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                stdOut.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }.start();
    //ErrorStream
    new Thread() {
        @Override
        public void run() {
            String line;
            try {
                while ((line = stdErr.readLine()) != null) {
                    debugOut(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                stdErr.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }.start();
    try {
        final Provider provider = new Provider();
        ExecutorService pEexec = Executors.newCachedThreadPool();
        Future<Void> FPExec = pEexec.submit(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                while (!Thread.currentThread().isInterrupted()) {
                    provider.run();
                }
                return null;
            }
        });
        pEexec.shutdown();
        process.waitFor();
        debugOut("[MainApp] Exit");
        provider.stop();
        FPExec.cancel(true);
        debug("Destroy process");
        process.destroy();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void startApp() {
    try {
        ArrayList<String> params = new ArrayList<String>();
        ...
        params.add("-Xms32M");
        params.add("-Xmx48M");
        params.add("-Xincgc");
        params.add("-cp");
        params.add(new File(pathToJar, "mainapp.jar").getPath());
        params.add("net.craftwork.mainapp.AppStart");
        params.add(licCode());
        ProcessBuilder procBuild = new ProcessBuilder(params);
        debugOut("[MainApp] Start");
        Process proc = procBuild.start();
        communicate(proc);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我相信这就是全部。即使在速度较慢的计算机上,整个设置也运行得非常好。问题是,在引入套接字接口之后,我们收到了一些用户的投诉,报告了崩溃。我们花了一些时间来解决这个问题,但我们发现:采用英特尔处理器的计算机非常好,只有采用AMD处理器的计算机才会崩溃。崩溃通常发生在启动后3到15分钟内。当崩溃发生时,计算机的资源并没有得到充分利用,处理器的工作负载约为20-50%,RAM也相当空闲。当崩溃发生时,用户只能使用硬件重置或电源按钮重置计算机,其他任何操作都不会响应。所有用户都拥有最新的JAVA 1.7.0_51。无论系统是32位还是64位,如果它是基于Intel的,则系统都会崩溃或不崩溃。请分享你的想法。可能有人有相同的问题,可以帮我解决。

什么会导致它崩溃?当它崩溃时捕获异常,记录该异常的调用堆栈,检查该异常以找出它崩溃的行,检查代码以找出它在该行上做了什么,修复它。或者,如果您无法修复它,请返回给我们一个更具体的问题,关于为什么在这种情况下,该行出现问题。当然,我们会记录所有内容。在主应用程序中,所有日志都发送到System.out,引导程序捕获主应用程序的所有事件,并通过System.setOut将所有内容记录到日志文件中。但是我们这里有一个系统的全站,当所有的服务都关闭,整个系统没有响应时,因此我们不仅不能获取应用程序的日志,也不能获取系统日志,在崩溃期间,甚至没有写入Windows日志。系统重新启动后,我们得到的第一个日志条目是system was reboot。因此,我们没有任何关于代码哪一部分导致问题的额外信息。唯一的线索是,如果我们在主应用程序的Bootstrap和Requester.main中删除SocketServer start的线程,AMD系统不会遇到此类问题。再一次,英特尔系统根本没有遇到任何问题,问题只出现在AMD系统上。这可能与著名的Livelock错误有关-请参阅
public class Requester {
    Socket requestSocket;
    ObjectOutputStream out;
    ObjectInputStream in;
    String message;
    static Future<Void> oExec;

    Requester() {
    }

    void run() {
        try {
            requestSocket = new Socket("localhost", 54345);
            out = new ObjectOutputStream(requestSocket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(requestSocket.getInputStream());
            do {
                try {
                    message = (String)in.readObject();
                    sendMessage("bye");
                } catch(ClassNotFoundException cnfe) {
                    cnfe.printStackTrace();
                }
            } while (!message.equals("bye"));
        } catch(UnknownHostException uhe) {
            uhe.printStackTrace();
        } catch(IOException ioe) {
            ioe.printStackTrace();
            oExec.cancel(true);
            CommonUtils.debug("Bootstrap not found. Exit.");
            System.exit(0);
        } finally {
            try {
                in.close();
                out.close();
                requestSocket.close();
            } catch(IOException ioef) {
                ioef.printStackTrace();
            }
        }
    }

    void sendMessage(String msg) {
        try {
            out.writeObject(msg);
            out.flush();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public static void main() {
        final Requester client = new Requester();
        ExecutorService exec = Executors.newCachedThreadPool();
        oExec = exec.submit(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                while (!Thread.currentThread().isInterrupted()) {
                    client.run();
                    Thread.sleep(1000);
                }
                return null;
            }
        });
        exec.shutdown();
    }
}
public class AppStart {
    public static void main(final String[] args) {
        Requester.main();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                ...
            }
        });
    }
}