代码之家  ›  专栏  ›  技术社区  ›  Ibrahim

64位JVM中是否有任何错误或不兼容?

  •  0
  • Ibrahim  · 技术社区  · 16 年前

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

    我们的游戏是网络化和多线程的,我认为我们在同步东西的方式上有一些问题(我以前写同步的时候还没有完全理解同步的整个概念),例如我们已经使run()方法同步了,这没有任何效果,但是尽管我们的大部分代码都是愚蠢的,但是这些东西仍然在32 B上运行。IT JVM(Windows和Linux)。

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

    有什么问题吗?我们的密码在上面 github 如果有人想看看。如果你这样做的话,我会非常高兴,但我不希望有人涉过我们丑陋的代码。谢谢!

    顺便说一下,我们都在64位Windows Vista和JDK 1.6 U12和U14上运行,但是我们也在运行Linux,尽管我还没有在64位Linux JVM上测试过它。 哦,关于为什么我非常确定它是64位的JVM Issue的更多细节:

    所以我们基本上是在秋季学期研究这个问题的,暂时停止了。6个月后,我们再次拿起它,错开我们可怕的代码,并开始尝试清理它。然后我们意识到我们两个都不能正常运行它。我试着找到一个有效的版本,但是我从今年夏天开始工作之前的最后一个版本开始,它仍然不起作用。然后我甚至检查了一些我以前编译过的二进制文件(.jar),甚至最早的版本也不能在64位JVM上工作。然后我检查了运行sun jdk1.6jvm的32位Linux虚拟机,它工作得很好。因此,我非常确定这是一个64位的问题,因为在相同的二进制文件完美运行之前。

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

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

    哦,还有一件事,在Linux下运行openjdk 6 64位时也会遇到同样的问题。我猜这是64位版本所带来的竞争条件。

    4 回复  |  直到 14 年前
        1
  •  1
  •   Michael Borgwardt    16 年前

    游戏从一个人开始 主持一场比赛,然后其他人可以加入 直到主人决定开始 游戏。然后它向所有人发送一个提示 球员们,问他们是否愿意 开始吧,如果大家都同意的话,比赛就开始了。 开始。64号发生了什么事 位jvm是发送消息, 但似乎反应是 迷路了什么,或者 服务器没有正确计数 每个人都是因为比赛 实际上还没有开始。事实上, 主机收到更多消息, 其他玩家得不到 在比赛开始的时候再往前一点, 但是服务器好像卡住了 某处。

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

    我不再担心64位和32位的问题,尝试诊断实际的问题。因为它涉及多台机器,不幸的是它将非常困难(这通常是与比赛条件)。

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

        2
  •  1
  •   Ibrahim    16 年前

    我们发现了问题所在。在一个部分有一个循环,在这个循环中,一个线程等待另一个线程正在处理的某个东西准备就绪,但它只是一段时间(!准备好了){}循环。在64位的JVM线程中似乎不会被抢占,因为在32位的JVM中,这个循环会被抢占,然后另一个线程会完成并将变量设置为true,但在64位的JVM中不会。我现在明白了,我们应该使用wait/notify和locks来完成这项工作,但至少暂时在其中抛出sleep()来修复它。不完全是一种竞争条件,更像是线程模型的一个怪癖,所以我不接受其他任何答案,因为它们没有回答我提出的问题。

        3
  •  0
  •   Amir Afghani    16 年前

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

        4
  •  0
  •   basszero    16 年前

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

    使用原始套接字的荣誉,但它们很难得到正确的答案。考虑为您的网络堆栈使用一个库,比如 Apache Mina 当然,除非项目的目标是编写自己的套接字代码。肯定读过了 quick start guide . 它是基于文本的协议,直接映射到您正在使用的内容。

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

    推荐文章