Java 64位JVM中是否存在任何错误或不兼容?

Java 64位JVM中是否存在任何错误或不兼容?,java,multithreading,networking,64-bit,jvm,Java,Multithreading,Networking,64 Bit,Jvm,我和一个朋友正在用Java编写一个小游戏。它的编码有点糟糕,我们正在进行重构,但这不是现在真正的问题。我们都有64位机器,我想之前我们都在使用32位JDK,但最近我遇到了一些问题,所以我删除了所有JDK并安装了最新的64位JDK,我不确定什么时候,但我的朋友现在也在运行64位JDK。我们的游戏在32位JDK中运行良好,但在64位版本中,游戏无法启动。我一直在尝试用eclipse调试它,但这有点痛苦 我们的游戏是网络化和多线程的,我认为我们在如何同步方面存在一些问题(在我之前编写它时,我没有完全理

我和一个朋友正在用Java编写一个小游戏。它的编码有点糟糕,我们正在进行重构,但这不是现在真正的问题。我们都有64位机器,我想之前我们都在使用32位JDK,但最近我遇到了一些问题,所以我删除了所有JDK并安装了最新的64位JDK,我不确定什么时候,但我的朋友现在也在运行64位JDK。我们的游戏在32位JDK中运行良好,但在64位版本中,游戏无法启动。我一直在尝试用eclipse调试它,但这有点痛苦

我们的游戏是网络化和多线程的,我认为我们在如何同步方面存在一些问题(在我之前编写它时,我没有完全理解同步的整个概念),例如,我们使run()方法同步,但没有效果,但是,尽管我们的大部分代码都很愚蠢,这些东西仍然在32位JVM(Windows和Linux)上运行

游戏开始时,一个人主持游戏,然后其他人可以加入,直到主持人决定开始游戏。然后它会向所有玩家发送一个提示,询问他们是否想要开始,如果所有人都说是,游戏就开始了。在64位JVM上发生的事情是,它发送消息,但似乎响应丢失了或是其他什么,或者服务器没有正确计算每个人都已发出的指令,因为游戏实际上没有启动。事实上,主机收到了其他玩家没有收到的更多消息,并且在开始游戏时走得更远,但服务器似乎在某个地方卡住了

你知道有什么问题吗?如果有人想看的话,我们的密码已经打开了。如果你这么做了,我会非常高兴,但我不希望有人会涉过我们难看的代码。谢谢

顺便说一下,我们都运行在64位WindowsVista和JDK1.6U12和u14上,但我们也运行Linux,尽管我还没有能够在64位Linux JVM上测试它。 哦,关于为什么我非常确定它是64位JVM的更多细节:

所以我们基本上是在秋季学期做这项工作的,并且有一段时间停止了这项工作。6个月后,我们又重新拾起它,在我们可怕的代码面前蹒跚而行,并开始尝试清理它。然后我们意识到我们两个都不能正常运行它。我试图找到一个有效的版本,但我找到了今年夏天开始工作之前的最后一个版本,但仍然不起作用。然后,我甚至检查了我以前编译过的一些二进制文件(.jar),即使是最早的版本也不能在64位JVM上使用。然后,我检查了一个运行Sun JDK1.6 JVM的32位Linux虚拟机,它运行得很好。因此,我很确定这是一个64位的问题,因为在相同的二进制文件完美工作之前

我还注意到,Vista在连接到我自己机器上的服务器(0:0:0:0:0:1,而不是127.0.0.1)时,出于某种原因将IPv6地址分配给我的套接字,但我修复了任何特定于IPv4的问题,它仍然不起作用

实际上,我刚刚在我的github存储库上创建了另一个问题,这是另一个悲惨的故事,所以我现在不能在另一台机器上测试我的最新版本。但重构前的最后一个构建在32位双核JVM上运行良好,因此看起来不像是竞争条件


哦,另一件事,完全相同的问题在Linux下的OpenJDK 6 64位下运行。我猜这是64位版本以某种方式带来的竞争条件。

您是否使用带-d64选项的java进程运行?如果不是,那么我很确定您仍然在32位模式下运行JVM,您的问题可能与环境或操作系统有关,而不是位

游戏开始时只有一个人 主持一个游戏,然后其他人可以加入 直到主机决定启动 游戏然后它向所有用户发送一个提示 球员们,问他们是否愿意 开始,如果所有人都同意,游戏开始 开始。64号公路上发生了什么 位JVM是它发送消息, 但似乎反应是 迷路什么的,或者 服务器的计数不正确 每个人都说了,因为比赛结束了 实际上并没有开始。事实上 主机收到的消息比 其他玩家未获得并获得 在比赛开始的时候, 但服务器似乎卡住了 某处

这听起来可能是一种竞争条件,即有缺陷或缺少同步。由于竞争条件取决于时间,几乎任何事情(包括切换JVM)都可能导致它们显化

我不再担心64位与32位的对比,而是尝试诊断实际问题。由于它涉及多台机器,不幸的是这将是非常困难的(这通常是在比赛条件下的情况)


最好的方法可能是确保所有机器都使用NTP同步时钟,然后使用毫秒时间戳记录消息的发送、接收和处理,以便您可以看到消息丢失或未正确处理的地方。

在这种情况下,我不希望64对32会导致任何问题,线程更可能是你的原因

使用原始套接字是值得称赞的,但它们很难正确使用。考虑将库用于网络堆栈,当然,除非项目的目标是编写自己的套接字代码。一定要通读一遍。它是基于文本的协议,直接映射到您正在使用的内容


旁注:在每个方法上保持同步和使用finalize都是坏东西/代码气味的症状

我们发现了问题所在。在一个部分中有一个循环,其中一个线程等待另一个线程正在处理的东西准备就绪,但它只是一个while(!ready){}循环。似乎在64位JVM中,线程不会被抢占,因为在32位JVM中,这个循环会被抢占,然后另一个线程会被抢占