Java 任意JVM行为
设想一个6-7台服务器的设置,所有服务器都是相同的 java版本“1.6.0_18” OpenJDK运行时环境(IcedTea6 1.8)(fedora-36.b18.fc11-i386) OpenJDK服务器虚拟机(构建14.0-b16,混合模式) 每个人运行一个程序(内存和CPU密集型)数小时甚至数天,成功完成多次(获取统计数据之类的东西),但在一台机器上,无论参数或我是如何编写的(javac-source 1.5*.java/javac-O-source 1.5,javac**,想象一下你自己的任何组合:)Java 任意JVM行为,java,jvm,openjdk,Java,Jvm,Openjdk,设想一个6-7台服务器的设置,所有服务器都是相同的 java版本“1.6.0_18” OpenJDK运行时环境(IcedTea6 1.8)(fedora-36.b18.fc11-i386) OpenJDK服务器虚拟机(构建14.0-b16,混合模式) 每个人运行一个程序(内存和CPU密集型)数小时甚至数天,成功完成多次(获取统计数据之类的东西),但在一台机器上,无论参数或我是如何编写的(javac-source 1.5*.java/javac-O-source 1.5,javac**,想象一下你
或者运行它(-xms20000k,或者只是java blabla.java,你明白了) 我最终得到了“java.lang.ArrayIndexOutOfBoundsException:-1341472392”,而不是在特定的时刻或迭代中?!首先,这个程序永远不会有这么大的值,更不用说负值了。(代码行是一个包含整数的ArrayList的contains调用)(正如我注意到的,这个数字每次都不同) 还要注意的是,我可以“恢复”崩溃的测试,并且我可以在这台机器上进行更多的测试,然后再次崩溃 不太麻烦,我没有自己的盒子和所有其他的工作,但这对我来说很奇怪
出于个人兴趣,这在不太乐观的OpenJDK上是如何发生的 听起来很奇怪。用于索引数组的变量是长变量,还是曾受长变量的影响?在这种情况下,不保证对变量的访问是原子的: 从 如果一个双变量或长变量未声明为volatile,则出于加载、存储、读取和写入操作的目的,它们被视为两个每个32位的变量:如果规则需要这些操作中的一个,则执行两个这样的操作,每32位的一半执行一个。双变量或长变量的64位编码为两个32位量的方式取决于实现。对易失性变量的加载、存储、读取和写入操作是原子的,即使变量的类型是double或long
如果您怀疑这可能是问题所在,您可以尝试将索引变量声明为volatile或使用其他一些同步方法(例如使用AtomicLong或类似方法)。如果这是单线程Java应用程序,我会怀疑硬件故障。当然,这可能很难证明,除非你有办法运行硬件(如内存)诊断。我唯一的想法是,这个neg值是由溢出引起的……你在不同的机器上测试过相同的输入数据吗?很好,是的,我做过,但它在其他每台机器上都运行得很好。“Other”在物理上是“Other”,但它们都有相同的硬件、软件和内存大小。有趣的是,索引变量是数组的元素,而数组又被另一个循环索引,但它们都是整数,是单线程的。我明白了,(作为对上述评论的回复)它唯一的命令行。