【问题标题】:Why https connections are so slow when debugging (stepping over) in Java?为什么在 Java 中调试(跨步)时 https 连接如此缓慢?
【发布时间】:2019-04-14 03:03:57
【问题描述】:

我正在尝试调试我的 Java 代码的一些问题,该代码建立了 http/https 连接。我想知道为什么在调试时连接变得异常缓慢(下载一个小网页超过一分钟),即使是在跨过网络工作的方法时也是如此。如果有一些补救措施。

下面我发布一个示例(您可以将 https: 更改为 http: ,并尝试从 Eclipse 中按 F11 进行调试 - 对于步进,在第一个 main() 语句中放置一个断点,然后按 F6当它停在那里时。

我的结果(以毫秒为单位的时间):

                        conn time   total time
http  (not stepping)        60           350
http  (stepping over)     1100          1500
https (not stepping)       570          1300
https (stepping over)    21000         83000

编辑:在禁用 Show method result after a step operation 选项后(howlger 的回答恰当地建议了补救措施),时间变得更加更加合理(大约是 https 的十分之一)。

http  (stepping over 2)     150           450
https (stepping over 2)    2000          7000

我的场景:Java 8 (1.8.0_121-b13),64 位,Win-7,Eclipse Photon(也有过 Oxygen 的经验)。

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;

public class TestConn {

    public static void downloadFromUrl(final URL url) throws IOException {
        long t0 = System.currentTimeMillis();
        URLConnection conn = url.openConnection();
        System.out.println("conn msecs: " +
              (System.currentTimeMillis() - t0) + " url=" + url);
        System.out.println("=====================================");
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
            String line;
            int cont = 0;
            while ((line = in.readLine()) != null) {
                if (cont++ < 4)
                    System.out.println(line);
            } 
            if(cont >=4) 
                System.out.printf("== total lines: %d (%d skipped)\n",cont,cont-4);
            System.out.println("==============done=======================");
        } 
    }

    public static void testConn(String urls) {
        try {
            long t0 = System.currentTimeMillis();
            downloadFromUrl(new URL(urls));
            System.out.println("Done , total time msecs: " + 
              (System.currentTimeMillis() - t0));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        testConn("https://www.example.com/"); // breakpoint here, step-over with F6
        System.out.println("bye");
    }
}

【问题讨论】:

  • 你没有衡量你认为自己是什么。一旦建立连接,套接字就会保持打开状态;所以它只需要连接一次。根据您的测试顺序,first 会很慢。然后之后的一切都更快。也就是说,您的调试器不是导致速度变慢的根本原因。
  • @ElliottFrisch :我的测量是在不同的运行中完成的,因此它们是不同的 JVM 实例,没有机会重用套接字。此外,我的结果不取决于顺序。无论如何,87 秒下载一个网页,即使是从最冷的状态,也是荒谬的。
  • 1) 当您连接调试代理并设置断点时,JVM 会取消优化代码。这可能会使其速度变慢。 2) 我怀疑 Java 团队是否付出了巨大的努力来使代码在调试时快速运行。为什么?因为大多数 Java 用户并不关心,而且将开发精力花在人们不关心的事情上是不好的工程。 3) “荒谬”是你的意见。 “荒谬”没有科学衡量标准。
  • 4) 如果你真的很在意....然后下载 OpenJDK 并开始调查 JVM 以找出速度慢的原因。找到原因后,开发补丁来修复它们并以标准方式提交给 OpenJDK 团队。
  • 除了4)没有补救措施。

标签: java eclipse debugging networking


【解决方案1】:

这就是为什么在 Window > Preferences: Java > Debug 中有首选项 Show method result after a step operation(如果 VM 支持; 可能很慢).

自 Eclipse 2018-09 (4.9) 起,可以为此设置超时(默认为 7 秒):

【讨论】:

  • 嗯,这个很有用。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多