当我调用 getInputStream 时,Java URLConnection 使整个过程崩溃

发布于 2024-07-25 23:38:18 字数 414 浏览 10 评论 0原文

我正在编写一个 Java 小程序,它从 Web 服务器下载图像并将其显示给用户。 它在 Java 1.6.0_3 及更高版本中工作正常,但在旧版本上,大约每 20 个页面浏览就会完全崩溃该进程。 Java 控制台中没有错误消息,因为该进程已完全冻结。 有时我等了将近15分钟,但它永远不会解冻。

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

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

以前有人遇到过这个问题吗? 知道如何修复它吗?

I am writing a Java applet that downloads images from a web server and displays them to the user. It works fine in Java 1.6.0_3 and later, but on older versions it will completely crash the process about once every 20 page views. There are no error messages in the Java console, because the process is completely frozen. I've waited for almost 15 minutes sometimes, but it never un-freezes.

I added a debug message after every line of code, and determined that the line that is causing the crash is this: InputStream data = urlConn.getInputStream().

urlConn is a URLConnection object that is pointed at the image I want to load. I've tried every combination of options that I can think of, but nothing helps. I haven't been able to find anything in the Java bug database or the release notes for 1.6.0_3.

Has anyone encountered this problem before? Any idea how to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

知你几分 2024-08-01 23:38:18

要确定是否确实是整个 JVM 进程被冻结,或者是其他什么情况:

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

(2)让另一个后台线程执行您可以观察到的操作; 它停止了吗?

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

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

如果在 Linux 上,您可以使用“netstat -t”或“lsof”(使用某些选项或 grep 只显示某些行)来查看打开的套接字; 如果每次获取后,又打开一个,并且计数永远不会减少,则说明您没有正确关闭事物。

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

它在后来的 Java 中“有效”的事实也表明:通过终结/GC 可能会更有效/定期地进行某种自动清理。 最好自己彻底关闭,但您也可以尝试在显示问题的早期 Java 中强制进行 GC/runFinalization。

To determine if it really is the whole JVM process that's frozen, or something else:

(1) get a java stack dump (sigquit/ctrl-break/jstack)

(2) have another background thread doing something you can observe; does it stop?

(3) check if another process (browser/etc) can contact server during freeze? (There's a chance the real problem is server connection depletion)

Is it randomly once-in-every-20-fetches (for example, 5% of the time, sometimes the first fetch in the JVM run), or always after about 20 fetches? If the latter, it sounds like something isn't being closed properly.

If on Linux you can use 'netstat -t' or 'lsof' (with certain options or grepped to show only some lines) to see open sockets; if after each fetch, one more is open, and the count never goes down, you're not closing things properly.

If so, calling close() on the stream you get back and/or disconnect() on the HttpUrlConnection after each try may help. (There may also be more severe limits on the number of connections an applet can leave open, so you're hitting this more quickly than you would in a standalone app.)

The fact that it 'works' in later Javas is also suggestive that some sort of automatic cleanup might be happening more effectively/regularly by finalization/GC. It's best to close things up cleanly yourself but you could also try forcing a GC/runFinalization in the earlier Javas showing the problem.

格子衫的從容 2024-08-01 23:38:18

我不确定您所面临问题的原因,但我成功使用以下代码从小程序内同步加载图像(从 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;
}

I'm unsure the cause of the problem you are facing, but I use the following code successfully for synchronously loading images from within applets (loads from either jar file or the server):

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文