可以阻止JIT优化方法吗?

时间:2013-06-05 00:51:04

标签: java compiler-construction jit

我有一个代码,我想知道可以阻止JIT优化方法 clearArraySafely 吗? 是否有可能选择性地禁用部分代码的JIT?

或者我如何确定此代码不会被优化?

private static char[] password;

public static void clearArraySafely() {
    // Overwritting array
    for (int i = 0 ; i <= password.length; i++) {
       password[i] = 0;
       //System.out.print(i); // <- I don't want to do this trick to be sure
    }
    password = null;
}

是否有任何好的类来存储char数组的密码?

2 个答案:

答案 0 :(得分:2)

这个问题有两个答案:

  1. AFAIK,没有办法“关闭”某种方法的优化,而不会为所有方法关闭它。

  2. 您可以执行可能禁止您担心当前一代Java编译器的特定优化的事情。例如:

        private static char[] password;
        public static String dummy;
    
        public static void clearArraySafely() {
            // Overwritting array
            for (int i = 0 ; i <= password.length; i++) {
               password[i] = 0;
            }
            dummy = new String(password);
            password = null;
        }
    

    JIT编译器无法优化零分配。如果是,那么将使用“错误”内容创建虚拟字符串。由于dummy可以通过反射访问而不会破坏任何JLS规则,因此JIT无法应用转义分析来避免创建它。

    但请注意,总有可能会有一些下一代JIT编译器......更加聪明。如果你想避免这种情况,你需要确保dummy以某种方式影响程序的输出;例如通过打印它。

  3.   

    是否有任何好的类来存储char数组的密码?

    AFAIK,没有人会遇到同样的问题。


    话说回到这个级别来保护密码是(IMO)接近偏执狂。如果某人具有从堆中无法访问的对象中窃取密码所需的访问级别,则他们很可能以其他方式获取密码;例如通过截取OS级别的字符,或“调试”JVM。


      

    我的偏执与调试JVM有关。

    不幸的是,你的妄想症无济于事。

    例如,您设计用于阻止某人连接调试器的方案可以通过逆向工程然后修改exe文件来解决。您设计的任何其他方案也是如此。

    如果用户控制执行程序的平台,则无法阻止他/她“调试”正在运行的程序。防止它的唯一方法是仅在控制的平台上运行应用程序。

    (BTW - 这不是Java特有的问题。它适用于所有编程语言。有些比其他语言更容易“破解”,但如果不道德的用户熟练,他们可以所有被黑客攻击并有动力,并有时间发展“黑客”。)

答案 1 :(得分:0)

编译器无法优化那些分配,因为它不知道是否对该数组有其他引用。变量password是对数组的引用,而不是对实际数组的引用。考虑一下:

char[] passwordCopy = password;
clearArraySafely();
// do something with passwordCopy

如果编译器删除了调零,则此代码将中断。如果Java使用引用计数,那么我认为如果refcount为1,它可以“优化”它,但这似乎不值得做。大多数情况下,人们不是在编写代码来更改后来被丢弃的东西。

您可能还想考虑使用GuardedString