2009-07-02 29 views
0

私は友人と私がJavaで書いているという小さなゲームを持っています。これはひどくコード化されており、リファクタリングに取り組んでいますが、それは今のところ問題ではありません。我々の両方が64ビットマシンを持っていると我々は両方の32ビットJDKを使用していた前に、私は推測するが、最近、私はいくつかの問題を持っていたので、私はすべてのJDKを削除し、最新の64ビットJDKをインストールして、私は時にはよく分からないが、私の友人でもあります64ビットJDKを実行しています。私たちのゲームは32ビットJDKで正常に動作していましたが、64ビットバージョンではゲームは開始しません。私は日食でそれをデバッグしようとしてきましたが、それは少し痛みでした。64ビットJVMのバグや非互換性はありますか?

当社のゲームは、ネットワークとマルチスレッドであり、私たちは私たちが物事を同期する方法をいくつかの問題を(私は前にそれを書いていたとき、私は完全に同期の全体的なアイデアを理解していない)などがあると思います。私たちは、実行()メソッドは効果がありませんどの同期していたが、私たちのコードの大部分の愚かにもかかわらず、ものはまだ32ビットJVM(WindowsおよびLinux)上で実行されます。一人がゲームをホストする場所

ゲームが起動し、ホストがゲームを開始することを決定するまで、他の人が参加することができます。その後、すべてのプレイヤーにプロンプ​​トを送信して、開始するかどうかを尋ね、すべてが「はい」と答えた場合、ゲームが開始されます。どのような64ビットJVM上で起こっていることは、それがメッセージを送信することですが、応答が失われたか何か、またはサーバはゲームが実際に開始されないため、誰もがOKedたことを正確にカウントされていないばかりいるように思えます。実際には、ホストは、他のプレイヤーが取得していないメッセージをもう少し受け取って、ゲームを始めるのに少し余裕ができますが、サーバーはどこかに詰まっているようです。

問題が何であるか任意のアイデア?誰かが見たいと思えば私達のコードはgithubに上がっています。あなたがしたら私は非常に満足しているだろうが、誰かが私たちの醜いコードを歩き回ることを期待していない。ありがとう!

ところで、私たちは64ビットWindows VistaとJDK 1.6 u12とu14の両方で動作していますが、64ビットLinux JVMでまだテストすることはできませんでしたが、Linuxも実行します。 ああ、私が64ビットJVMを発行している理由についてもっと詳しく知りたいのですが:

私たちは基本的に秋セメスターでこれをやっていましたし、しばらく作業をやめました。 6ヵ月後、私たちはそれをもう一度手に取って、私たちの恐ろしいコードをずらして、それをきれいにしようとします。それから、私たちのどちらも、それを適切に実行できないことを認識します。私は動作するリビジョンを見つけようとしますが、今夏に作業を開始する前から最後のリビジョンになりますが、まだ動作していません。私は以前にコンパイルしたバイナリ(.jars)をチェックしても、64ビットJVMでは動作しませんでした。私はその後、Sun JDK1.6 JVMを実行している32ビットのLinux VMをチェックし、うまくいきました。したがって、同じバイナリが完全に動作する前から64ビット問題だとはっきりと確信しています。

自分のマシン(127.0.0.1ではなく0:0:0:0:1)上のサーバーに接続するときに、何らかの理由でVistaが自分のソケットにIPv6アドレスを割り当てていることにも気付きました。私はIPv4固有のものはすべて修正していますが、まだ動作していません。

私は実際に私のgithubリポジトリに別の問題を作成しましたが、それは別のマシンで最新のビルドをテストすることはできません。しかし、リファクタリング前の最後のビルドは32ビットJVM上でデュアルコアでうまく動作するため、競合状態には見えません。

他にも、LinuxでOpenJDK 6 64ビットで動作する全く同じ問題。私はそれが64ビットバージョンが何とか持ち出す競争状態だと思っています。

+0

なぜ64bit JVMをまったく使用する必要があると思いますか?私が知っている唯一の利点は、許容されるヒープサイズが大きいことです。それはビッグアイアンのサーバーにのみ関連しています。 – skaffman

+0

理由はありません。私はちょうどそれをインストールしたばかりです。要点は、64ビットJVMまたは私自身のコードの根底にある問題のために、私が持っている問題があるかどうかを知りたいということです。私は今、後者に向かっている。 – Ibrahim

答えて

1

をにおいがします。 1つの部分にループがあり、そこではスレッドが別のスレッドが作業している準備が整うまで待っていましたが、ちょうど(!ready){}ループでした。 64ビットJVMスレッドでは、32ビットJVMではこのループがプリエンプトされ、その後もう1つのスレッドが終了して変数をtrueに設定し、64ビットJVMでは設定しないため、プリエンプションなどは行われません。私は、これを行うために待機/通知とロックを使用すべきであったが、一時的にそれを修正して睡眠を投げていたことが分かった。まさに競合状態ではなく、スレッドモデルの奇妙なもののように思われるので、私が質問した質問に彼らが答えなかったので、私は他の答えのどれも受け入れません。

+2

いいえ、スレッドは常に優先されます。 JVMが値をキャッシュすることができ、ローカルスレッドでそれを変更していないので、変更が表示されない(または、何らかのランダムな点で表示されます)つまり、このような値でビジー待機しないでください! –

+0

ああ、大丈夫です。それは理にかなっています。どちらの方法でも、whileループは、すべてのスレッドコードを修正するために外に出ています。同期の大部分は大変間違っています。なぜなら、同期が何をしているのか、そして何か誤解しているのかをほとんど理解していなかったからです。待機/通知は、おそらく私がここでやりたいことです。 – Ibrahim

0

Javaプロセスで-d64オプションを指定して実行していますか?もしそうでなければ、私はあなたがまだ32ビットモードでJVMを実行していると確信しています。あなたの問題は、ビットの代わりに環境やOSに関係するかもしれません。1人は ゲームをホストしているところ

+0

私はそうではありませんが、デフォルトでは64ビットモードで動作するという印象を受けました。実際には、プログラムは32ビットJVMでうまく動作するので、何かが間違っています。オリジナルの投稿にいくつかの詳細を追加する必要があります。これは、これが64ビットの問題であると確信していますが、本当にそうすべきではありません。 – Ibrahim

+0

32ビットと64ビットのどちらのJVMを使用しているのかを検出するのはかなり難しいです。彼らはまったく同じように実行します。 1つのJVMに表示される競合状態は存在しますが、他のJVMには表示されない可能性が高くなります。 –

1

は、ゲームが起動し、ホストが ゲームを開始することを決定するまで、他の人が に参加することができます。その後、 を開始するかどうかを尋ねるすべてのプレーヤーに のプロンプトを送信し、すべてがyesと答えた場合、ゲーム が開始されます。何64 ビットJVM上で起こっていること、それは、メッセージを送信し が、応答が 迷子か何か、または サーバは「ゲームは doesnのため 誰もがOKedたことを正確にカウントされていないあるようにそれが思われることです実際に開始する。実際には、 ホストは、 の他のプレイヤーが取得していないメッセージをもう一度入手し、 をゲームの開始に少しだけ近づけますが、サーバーは のどこかに固着しているようです。

これは競合状態、つまり欠陥のある同期の欠落のようです。競合状態はタイミングに依存するため、ほとんどのもの(スイッチングJVMを含む)がそれらを引き起こす可能性があります。

私は64bitと32bitについて心配するのをやめ、実際の問題を診断しようとします。複数のマシンが関わっているので、残念ながら非常に難しくなります(一般的には競合状態の場合です)。

これを行う最良の方法は、おそらくすべてのマシンがNTPを使用してクロックを同期していることを確認し、ミリ秒のタイムスタンプを持つメッセージの送信、受信、処理をログに記録して、正しく。私はこのケースではすべての問題を引き起こすために64対32を期待していない

+0

ええと、私は競合状態かもしれないと思っていましたが、別のJVMが異なるタイミング特性を持っていて、問題を引き起こす可能性があることに気づいていませんでした。私はほぼ間違った同期があることを確信していますので、公平なコードを精査しなければなりません。 私は言及したように根本的な問題を見つけようとしていますが、Eclipseでのマルチスレッドアプリケーションのデバッグは苦痛であり、32ビットJVMで正常に動作します。これが私が64ビットJVMの問題について尋ねた唯一の理由です。 – Ibrahim

+0

32ビットマシンがシングルコアで、64ビットマシンがマルチコアであってもかまいませんか?複数のコアを使用すると、潜在的なスレッド問題が発生する可能性が高くなります。しかし、私はbitnessが根本的な問題であるとは思わないことに同意します。 – Nathan

0

、スレッドはrawソケットを使用するための

賛辞あなたの原因となることへの道がより可能性が高いですが、彼らは正しい取得するのは非常に難しいです。 Apache Minaのように、ネットワークスタック用のライブラリを使用することを検討してください。もちろん、プロジェクトの目標は独自のソケットコードを書くことです。間違いなくquick start guideを読んでください。テキストベースのプロトコルは、使用しているものに直接マッピングされます。

サイドノート:すべてのメソッドに同期され、確定使用して貼り付き悪いこと/コードの症状です私たちは、問題が何であったかが分かった

+0

ええ、確かにそこに多くの悪いコードがあります。私は生のソケットについて何がそんなに難しいのか分かりません。いずれにせよ、それはここで問題ではありません。私はそれが競争条件であることを今確信していますが、それを確認するまでには時間がかかるでしょう。私はその間に32ビットJVMに戻ってくると思います。 – Ibrahim

+0

rawソケットは問題ありませんが、通常は簡単に条件を競合できるスレッドと組み合わされています。 MINAを使用する私の提案は、ネットワーキングスタックをスキップし、面白いゲームを書くことに集中できます! – basszero

関連する問題