本报告详细介绍了构建Tencent Kona JDK 17的完整过程,以及如何实现用于测试EC和RSA密钥对生成器性能的JMH基准测试程序。该项目的主要目标是:
以下是我的设备和环境的配置信息:
/usr/lib/jvm/java-17-openjdk-amd64/home/xsj/jmh/jars在开始构建之前,建议运行以下检查脚本验证您的环境配置:
echo "=== 环境检查报告 ==="
echo "=== Java环境 ==="
java -version
echo "Java路径: $(which java)"
echo -e "\n=== JMH组件检查 ==="
find ~ -name "*jmh*" -type f 2>/dev/null | head -10
find ~ -name "*.jar" | grep -E "(jmh|jopt|commons)" 2>/dev/null
echo -e "\n=== 系统信息 ==="
uname -a
gcc --version | head -1
make --version | head -1
echo -e "\n=== 构建工具检查 ==="
autoconf --version | head -1
# 确认WSL2版本
wsl --version
# 进入WSL2环境
wsl.exe
# 安装基础构建工具
sudo apt-get install -y \
make \
build-essential \
autoconf \
wget
# 安装JDK构建所需的开发库
sudo apt-get install -y \
libasound2-dev \
libcups2-dev \
libffi-dev
libfreetype6-dev \
libx11-dev \
libxext-dev \
libxrender-dev \
libxrandr-dev \
libxtst-dev \
libxt-dev \
# 确认Boot JDK路径(已验证的实际路径)
export BOOT_JDK_PATH="/usr/lib/jvm/java-17-openjdk-amd64"
java -version # 验证Boot JDK配置成功
#在项目根目录下执行以下命令获取JMH依赖:
bash make/devkit/createJMHBundle.sh
完全清理(包括配置):
# 进入Kona JDK源码目录(根据您的实际路径)
cd ~/TencentKona-17.0.16
# 完全清理构建目录和配置
rm -rf build/
仅清理编译产物(保留配置):
# 如果只想清理编译产物而保留configure配置
make clean
# 或者更彻底的清理(但保留配置)
make dist-clean
说明:
rm -rf build/:完全删除构建目录,需要重新运行configuremake clean:只清理编译产物,保留configure生成的配置文件make dist-clean:清理更多临时文件,但仍保留配置简化版本(推荐):
./configure \ --build=x86_64-linux-gnu \ --host=x86_64-linux-gnu \ --target=x86_64-linux-gnu \ --with-toolchain-type=gcc \ --with-jmh=build/jmh/jars
完整版本(显式指定所有参数):
./configure \ --with-debug-level=release \ --with-native-debug-symbols=internal \ --with-jvm-variants=server \ --enable-unlimited-crypto \ --disable-warnings-as-errors \ --with-toolchain-type=gcc \ --with-boot-jdk=/usr/lib/jvm/java-17-openjdk-amd64 \ --with-jmh=build/jmh/jars
参数说明:
make make build-microbenchmark
# 设置构建后的JDK环境变量
export JAVA_HOME="$PWD/build/linux-x86_64-server-release/images/jdk"
export PATH="$JAVA_HOME/bin:$PATH"
# 验证JDK版本
java -version
我写了两个独立的JMH基准测试类:
在进行上述环境配置和JDK构建之后,运行如下命令即可执行JMH测试类:
# 运行EC密钥对生成器测试
make test TEST="micro:ECKeyPairGeneratorBench" MICRO="OPTIONS=-prof gc"
# 运行RSA密钥对生成器测试
make test TEST="micro:RSAKeyPairGeneratorBench" MICRO="OPTIONS=-prof gc"
package org.openjdk.bench.java.security;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
@Fork(value = 3)
public class ECKeyPairGeneratorBench {
@Param({"SunEC"})
private String provider;
@Param({"secp256r1", "secp384r1", "secp521r1"})
private String curve;
private KeyPairGenerator kpg;
private SecureRandom random;
@Setup(Level.Trial)
public void setup() throws Exception {
random = new SecureRandom();
kpg = KeyPairGenerator.getInstance("EC", provider);
kpg.initialize(new ECGenParameterSpec(curve), random);
}
@Benchmark
public KeyPair generate() {
return kpg.generateKeyPair();
}
}
package org.openjdk.bench.java.security;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Thread)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
@Fork(value = 3)
public class RSAKeyPairGeneratorBench {
@Param({"SunRsaSign"})
private String provider;
@Param({"2048", "3072", "4096"})
private int keySize;
private KeyPairGenerator kpg;
private SecureRandom random;
@Setup(Level.Trial)
public void setup() throws Exception {
random = new SecureRandom();
kpg = KeyPairGenerator.getInstance("RSA", provider);
kpg.initialize(new RSAKeyGenParameterSpec(keySize, RSAKeyGenParameterSpec.F4), random);
}
@Benchmark
public KeyPair generate() {
return kpg.generateKeyPair();
}
}