【问题标题】:Java application performs very slow (10-100 times slower than on Windows, Linux, AIX)Java 应用程序执行速度非常慢(比 Windows、Linux、AIX 慢 10-100 倍)
【发布时间】:2013-05-21 23:27:14
【问题描述】:

关于在 HP\UX 服务器上运行我们的公司 Java 应用程序的性能问题,我需要您的帮助。应用程序是一个独立的工具,它将多个数据库上的数据同步为一个,通过 XML-RPC 协议与远程控制通信,并使用本地 Derby (Java DB) 数据库实例来保存配置数据等。我们在其他环境上没有性能问题与使用 Sun JVM 的 Windows XP、Linux 和 AIX 相同的负载。经过一系列测试,我们发现最耗时的是与 Derby 数据库的通信。大部分时间都花在了从套接字读取上,这个时间比其他平台要多 10-100 倍。我们确信 Derby 工作正常,我们有 CPU 储备(使用率约为 30%-40%),所以最可能的原因是本地数据库和应用程序之间的传输层。

有没有办法诊断 HP-UX 上的套接字 I\O 问题,或者可能存在一些可以配置的限制?也许有必要的JVM选项?非常感谢您提出的任何想法。

我们尝试根据 http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=/com.ibm.websphere.wsfep.multiplatform.doc/info/ae/ae/tprf_tunejvm_v61.html 优化 JVM 选项,但没有得到任何显着改进。

JVM 信息: Java HotSpot(TM) 64 位服务器 VM(19.1-b02-jinteg:2011mar11-16:46 PA2.0W (aCC_AP),混合模式) Java:版本 1.6.0.10,供应商“惠普公司”

我们使用以下实例: 操作系统:HP-UX (B.11.23) 架构:PA_RISC2.0W 64bit 处理器:2

总物理内存大小:4 088 MB 交换大小:4 090 MB

这是运行缓慢的代码示例。在 HP 上执行需要几秒钟,而在 Windows 上需要 10-30 毫秒:

/** Template to communicate with local db. */
SimpleJdbcTemplate jdbcTemplate;

@Transactional(readOnly = true)
public List<JobLogEntry> getLastLogs(Integer dbnr, JobDataType dtype) {
    try {
        String uid = jdbcTemplate.queryForObject("SELECT session_uuid FROM "
                                                         + tableName + " WHERE id=(SELECT max(id) FROM "
                                                         + tableName + " WHERE dbnr=? AND dtype=?)",
                                                         String.class, dbnr, dtype.name());
        List<JobLogEntry> list = jdbcTemplate.query("SELECT id, dbnr, dtype, zeit, level, message FROM "
                                                             + tableName
                                                             + " WHERE dbnr=? AND dtype=? AND session_uuid=? ORDER BY ID",
                                                             new ConRowMapper(), dbnr, dtype.name(), uid);
        return list;
    } catch (org.springframework.dao.EmptyResultDataAccessException e) {
        return new ArrayList<JobLogEntry>();
    }
}



class ConRowMapper implements RowMapper<JobLogEntry> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");

    /**
     * Maps rows.
     */
    public JobLogEntry mapRow(ResultSet rs, int rowNum) throws SQLException {
        return new JobLogEntry(rs.getInt("dbnr"), 
                               rs.getString("dtype"), 
                               dateFormat.format(rs.getTimestamp("zeit")), 
                               rs.getString("level"), 
                               rs.getString("message"));
    }
}

提前感谢您的所有想法

【问题讨论】:

  • 您当前的 JVM 设置是什么,为什么您认为问题出在传输层?您是否分析过您的应用程序甚至连接了 JConsole 等?引用的时间是否仅针对第一次执行?

标签: java performance hp-ux


【解决方案1】:

我想知道getLastLogs()这个方法。为什么要查询以获取会话 UUID,然后转身在另一个查询中使用它?我猜想可以在一个查询中完成。

当您说 Derby 时,我觉得只有 Java 才能访问该数据库。真的吗?你知道它优化得很好(例如,每个 WHERE 子句都有适当的索引)吗?

您使用连接池吗?这样您就可以预先支付创建连接的成本,并将其分摊到您运行的所有查询中。

我看到 jdbcTemplate,所以你一定是在使用 Spring。我会连接调试或跟踪拦截器,看看时间花在了哪里。

我还推荐 Visual VM 1.3.2 将安装所有插件。它将为您提供更多数据。

【讨论】:

  • 你好达菲莫。谢谢你的回答。是的,我们正在使用 Derby 索引和连接池。最奇怪的是,在所有其他系统上,应用程序的运行速度都非常快。 VisualVM 说应用程序大部分时间都停留在方法中。我们认为可能另一个 jvm 线程会影响性能。可能不是代码中的问题。你怎么看?
  • 可能 GC 会影响我们的性能?会不会是 HP JVM 的性能比 Sun 的差很多?
  • 不知道,安德烈。我会将 VisualVM 1.3.2 连接到您的应用程序并获取更多信息。我们俩都是在没有数据的情况下猜测。
【解决方案2】:

可能的原因可能是 HP-UX 上的 GC 运行缓慢且阻塞。尝试删除多余的 System.gc() 调用并使用一些 JVM GC 选项来优化 :)

查看有关 HP 性能调整的精彩演示:http://www.scribd.com/doc/47433278/Javamemorymanagemen

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 2011-01-24
    • 2013-12-05
    • 2010-12-22
    相关资源
    最近更新 更多