关于AES-NI,Oracle有关于Java 8的说法:
添加了硬件内在函数以使用高级加密标准 (AES)。 UseAES和UseAESIntrinsics标志可用于启用 基于硬件的英特尔硬件AES内在函数。硬件 必须是2010年或更新的Westmere硬件。例如,要启用 硬件AES,使用以下标志:
-XX:+UseAES -XX:+UseAESIntrinsics
要禁用硬件AES,请使用以下标志:
-XX:-UseAES -XX:-UseAESIntrinsics
但它并不表示默认情况下是否启用AES内在函数(对于支持它的处理器)。所以问题很简单:如果处理器支持AES-NI,是否使用了AES内在函数?
奖金问题:有没有办法测试是否使用AES-NI?我想你可以根据性能进行猜测,但这不是最佳或确定的测试方法。
对于不熟悉AES-NI内在函数的读者:它使用AES-NI指令集用预编译的机器代码替换字节代码。这是由JVM发生的,因此它不会出现在Java运行时或字节码的API中。
答案 0 :(得分:32)
该标志的默认值为true,如果检测失败,它将被设置为false,因此您只需使用+ PrintFlagsFinal查看是否使用它:
我的笔记本电脑没有 AES-NI:
C:\>"C:\Program Files\Java\jdk1.7.0_51\bin\java" -XX:+PrintFlagsFinal -version | find "UseAES"
bool UseAES = false {product}
bool UseAESIntrinsics = false {product}
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
桌面与 AES-NI相同:
C:\>"C:\Program Files\Java\jdk7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
bool UseAES = true {product}
bool UseAESIntrinsics = true {product}
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
C:\>"C:\Program Files (x86)\Java\jre7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
bool UseAES = true {product}
bool UseAESIntrinsics = true {product}
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) Client VM (build 24.51-b03, mixed mode, sharing)
因此,它适用于最新Java 7的x64和i686(WOW64)。该功能随https://bugs.openjdk.java.net/browse/JDK-7184394一起引入,并向后移植到7u40和7u45。
重要提示:AES-NI可能仅在服务器VM 上可用。
Oracle在a bug report was filed之后承认了这一点。当他们创建引入它的Java 8的特征列表时,这个至关重要的信息就丢失了(后来它也被反向移植到7)。可以通过在-server
或java
命令行上提供javaw
选项来明确选择服务器VM。
答案 1 :(得分:4)
无法发表评论(愚蠢的SO规则要求超过50个学分!)。 This mailthread from openjdk表示,默认情况下会启用所有AES内在函数。虽然我不确定有多少Oracle核心VM代码与openjdk共享。 如果您阅读整个线程,他们还会讨论32位虚拟机上的挑战,这可能解释了您的第二次测试运行时遇到的问题。