当我调用getInputStream时,Java URLConnection会崩溃整个进程

时间:2009-07-02 21:00:12

标签: java applet urlconnection

我正在编写一个Java applet,它从Web服务器下载图像并将其显示给用户。它在Java 1.6.0_3及更高版本中运行良好,但在旧版本上,它将使每20次页面查看完全崩溃一次。 Java控制台中没有错误消息,因为该过程已完全冻结。我有时候会等待将近15分钟,但它永远不会冻结。

我在每行代码后添加了一条调试消息,并确定导致崩溃的行是:InputStream data = urlConn.getInputStream()

urlConn是一个URLConnection对象,指向我要加载的图像。我已经尝试了我能想到的各种选项组合,但没有任何帮助。我无法在Java bug数据库或1.6.0_3的发行说明中找到任何内容。

以前有人遇到过这个问题吗?知道怎么解决吗?

2 个答案:

答案 0 :(得分:1)

确定它是否真的是整个JVM进程被冻结或其他:

(1)获取java堆栈转储(sigquit / ctrl-break / jstack)

(2)让另一个背景线程做你能观察到的事情;它会停止吗?

(3)检查另一个进程(浏览器/等)是否可以在冻结期间联系服务器? (真正的问题是服务器连接耗尽的可能性)

它是随机每次20次提取(例如,5%的时间,有时是JVM运行中的第一次提取),还是总是在大约20次提取后?如果是后者,听起来好像没有正确关闭。

如果在Linux上你可以使用'netstat -t'或'lsof'(带某些选项或grepped只显示一些行)来查看打开的套接字;如果在每次获取之后,还有一个是打开的,并且计数永远不会下降,你没有正确地关闭它。

如果是这样,在每次尝试后调用HttpUrlConnection上的流返回和/或断开()的close()可能会有所帮助。 (对于applet可以保持打开的连接数量,可能还有更严格的限制,因此您可以比在独立应用程序中更快地进行此操作。)

它在后来的Javas中“起作用”的事实也暗示了最终化/ GC可以更有效/更有效地进行某种自动清理。最好自己干净地关闭一些东西,但你也可以尝试在早期的Javas中强制GC / runFinalization显示问题。

答案 1 :(得分:0)

我不确定您遇到的问题的原因,但我成功使用以下代码从applet中同步加载图像(从jar文件或服务器加载):

public Image loadImage(String imageName) {

    // get the image
    Image image = getImage(getCodeBase(), imageName);

    // wait for it to fully load
    MediaTracker tracker = new MediaTracker(this);
    tracker.addImage(image, 0);
    boolean interrupted = false;
    try {
        tracker.waitForID(0);
    } catch (InterruptedException e) {
        interrupted = true;
    }

    int status = tracker.statusID(thisImageTrackerID, false);
    if (status != MediaTracker.COMPLETE) {
        throw new RuntimeException("Failed to load " + imageName + ", interrupted:" + interrupted + ", status:" + status);
    }

    return image;
}