对于 SQL 解析,我们在 Java Web 应用程序中使用通用 SQL 解析器(GSP)。如果我们在带有 Java 7 的 Windows Server 2008 R2 上使用 GSP 部署我们的应用程序,我们会在类加载期间看到 100% 的 CPU 峰值,这可能会持续几分钟。在初始类加载后一切正常,直到我们关闭应用程序服务器并且类被卸载:100% CPU 峰值又回来了。如果我们将相同的代码库部署到 Windows Server 2012、Windows 7 Enterprise、OS X 或 Linux 服务器,则不会出现这样的峰值。在 Windows Server 2008 R2 上使用 Java 8 可以稍微改善启动。
使用 Microsoft 的 Process Monitor,我们看到从这个 jar 加载类时浪费了很多时间。gsp.jar 中的类文件被混淆了。我们可以排除除了新添加的 jar 之外的任何其他原因。只需解析一条 SQL 语句,冷启动时间就会显着增加。禁用防病毒软件没有任何效果。并非所有客户都可以选择升级到较新的 Windows Server 版本。
我们正在运行这个 GSP 版本:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.1
Created-By: 1.5.0_09-b01 (Sun Microsystems Inc.)
Built-By: Gudu Software
Vendor: Gudu Software
Title: General SQL Parser Java Version
Version: 1.6.0.5
这个测试程序在 Windows Server 2008 R2 上执行需要 40 多秒,在 OS X 上需要 1.5 秒。
package com.stackoverflow;
import gudusoft.gsqlparser.EDbVendor;
import gudusoft.gsqlparser.TGSqlParser;
public class TestGSP {
public static void main(String[] args) {
TGSqlParser parser = new TGSqlParser(EDbVendor.dbvmssql);
parser.setSqltext("select a from b where c = d");
parser.parse();
}
}
有谁知道是什么导致了这个问题以及如何避免它?
编辑 我采用了全新的 Windows Server 2008 R2 并使用不同的 RAM/JVM 设置运行测试程序:
例如:java -Xmx1G -classpath ".\;.\gsp.jar" com.stackoverflow.TestGSP
+--------------+-----------+----------------+
| Java version | RAM in GB | Duration in ms |
+--------------+-----------+----------------+
| 1.7.0_79 | 1 | 33438 |
| 1.7.0_79 | 2 | 33640 |
| 1.7.0_79 | 4 | 33484 |
| 1.8.0_66 | 1 | 5437 |
| 1.8.0_66 | 2 | 5563 |
| 1.8.0_66 | 4 | 5703 |
+--------------+-----------+----------------+
如果我在 OS XI 上运行相同的测试,得到这个持续时间:
+--------------+-----------+----------------+
| Java version | RAM in GB | Duration in ms |
+--------------+-----------+----------------+
| 1.7.0_79 | 1 | 1024 |
| 1.7.0_79 | 2 | 999 |
| 1.7.0_79 | 4 | 968 |
| 1.8.0_65 | 1 | 601 |
| 1.8.0_65 | 2 | 601 |
| 1.8.0_65 | 4 | 603 |
+--------------+-----------+----------------+
更改 JVM 版本会有所帮助,但增加 RAM 并不能解决问题。