パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

Java 1.4SE正式リリース」記事へのコメント

  • 未だにJava人気あるんですね。
    僕はいまいちJavaの良さが分かりません。
    誰かJavaのすばらしさを語ってもらえないでしょうか。
    • 「Java は駄目」とか言う人の話をよく聞いてみると、
      Java Applet のことだったり、 JavaScript のことだったりする
      ことがあるので、いっかい問い詰めてみたほうがいいです。
      • Re:Javaの必要性 (スコア:2, 参考になる)

        by loginPenguin (7275) on 2002年02月15日 11時13分 (#63037)
        僕がJavaで駄目だと思うところはまず実行速度です。
        JITの技術がありますが本質的な解決策では無いと思います。
        しかもテキスト処理なんかはJITを使ってもAwkよりもPerlよりも遅い。

        次に移植性です。
        Write Once Run Anywareとか言っていますがはっきり言って実現されて無いと思います。
        移植性 + 速度
        で考えるとCの方が上だと思っています。

        GCを利点として挙げる人がいますが、それも僕はどうかと思っています。
        GCがあるためにむちゃくちゃなプログラムでもある程度動いてしまいます。
        1時間ぐらいだったら動くけど長時間動かしているとVMが落ちることがありますし、その時のバグを見つけるのが非常に大変です。

        最後にIDEです。
        デバッグが難しいのにろくなIDEが無いために開発が非常に面倒です。

        後は思想的な話ですが、そもそもJavaが出てきた時のライセンスが僕は嫌いでした。
        「全ての環境で同じプログラムが動く。だからうちにお金を払ってね。」
        って思いっきり某社の戦略ですよね。
        今はライセンスが変わりましたが、それは単にJavaが最初のライセンスではやらなかったから変えただけであって、根本的な思想は某社と大して変わらない気がします。

        dan kamiyubiさんの意見をお聞かせ下さい。
        長文失礼しました。
        親コメント
        • Re:Javaの必要性 (スコア:3, 参考になる)

          by dan kamiyubi (6091) on 2002年02月15日 13時28分 (#63114) ホームページ 日記
          皆さんおっしゃられているとおり向き不向きの話だと思うので私の向いている
          方の話をすると、

          まず実行速度ですが、私の作ってるようなものだと他の要素、通信やデータベー
          スが遅いので、今Javaな部分をCで書いたところで数%も速くならない、むしろ
          開発速度が重要で、そういう意味では perl,python,ruby などの方が向いてる
          と思います。

          遅けりゃ負荷分散したらいいやん、ということで最近ではPCクラスタで分散オ
          ブジェクトとかすることが多いので、言語標準のライブラリで分散オブジェク
          トがしやすいのもありがたいです。

          移植性は、Cでは移植性のないコードも書き易いのでその点さすがにC以外の方
          がいいのでは。私の知るヘボCプログラマはすぐにリトルエンディアンを前提
          にコードを書くのでSPARCにもってくとき苦労しました。

          GCだめだからJavaだめってのは何とも…。他のオブジェクトを明示的に解放し
          ない言語もだめなんでしょうか。

          IDEは確かにあったほうが参入障壁は低いですね。初心者に勧め易いというか。
          私のほうでは必要ないので、無いことがデメリットにはなりません。Junitを
          使い出してからはいわゆるIDEでデバッグはしたことないです。バグがあった
          らまず再現性を出すテストを書きます。Javaは例外時スタックトレースが出る
          のでそれで分かることも多いです。あと再現性のだしづらいバグではIDE のあ
          り無しはデバグの容易さとは関係ありません。GUIだと例えばマウスを押して
          から離すまでの間動くコードのデバグなどはIDEがあっても楽にはなりません。

          思想的な話は良く分からないのでパス。まあ、まっとうなソフトウェア技術者
          ならC/C++、perl、python、java、lisp くらいは書けて当然なので「要は適材
          的所だ」で済むのではないでしょうか。
          親コメント
          • by loginPenguin (7275) on 2002年02月15日 13時52分 (#63126)
            非常に勉強になります。
            「Javaが適材適所の言語である」というのは納得してます。
            でも、僕が良く分からないのは適材適所で無いような気がする分野にまでJavaが持ち込まれているような気がします。
            例えばReal Time Javaなんていうのは本当に必要なのでしょうか。
            dan kamiyubiさんはおそらくJava信者では無いと思いますが、Java信者の人はよく「Java万能」と考えていることがあります。
            dan kamiyubiさんの目からみてJavaの可能性はどの程度あると思いますか?
            親コメント
            • 名指しで召喚するのは勘弁してほしいな。必要性とか可能性は、見出すものだと思う。RealTimeJavaは不勉強でよくしりませんけど、技術的に困難なことに挑戦する姿って尊いじゃないですか。RealTimeJavaにチャレンジしようとしているひとのやる気をそぎたくない。ぜひがんばってほしい。「Java万能」という人の理由は「(あらゆる場合に)Java捨て」という人の理由とたいして違わないでしょう。ほかの人も指摘してたけどJava実行環境とJava言語の違いがついてないのかもしれない。
              親コメント
            • ... のわけがないじゃないですか。

              (100% Pure Java にこだわると)Java 言語では
              (まともな) JavaVM が書けないのですから、、、

              p.s.

              任意のアドレスに任意の型でデータを読み書きできる
              バイトコードのプリミティブがあれば、比較的まともな
              速度で動く JavaVM が Java で書けるのです。

              そういうプリミティブがない場合は、しょうがないので
              ヒープ空間全体を覆うような強大な byte 型配列をとって、
              bastore と baload でちまちま読み込んで論理合成する
              しかない!?
              --
              コンタミは発見の母
              親コメント
          • by G7 (3009) on 2002年02月17日 0時53分 (#63642)
            >IDEは確かにあったほうが参入障壁は低いですね。初心者に勧め易いというか。

            オフトピですが、javaが、delphiくらいに
            「property」と「metaclass」の機能を持っていれば、
            もっとRADをエレガントに作れただろうに、と
            ちょっと残念に思っているところです。

            まぁJ++とかC#とかいう声もあるが(笑)、MS専用じゃあ、ちょっとね…

            delphiみたいに、強型で静的な言語であることと、
            RADに(ほかにも)役立つような動的性を持たせることとが、
            両立する言語ってのを作ることができるのは事実なわけで、
            それをやらなかったjavaってのが、なんともねえ。

            beanの仕様はborlandの協力のもと作ったそうですが、
            propertyもなにも無くコーディング規約(^^;で実現されるbean
            ってやつは、とても半端な代物に見えますし、
            クラスメソッドの多態ができないことによって
            たとえばClass#newInstance()が「引数のないconstructorしか呼べない」
            などという間抜けな制限があるわけで、
            borland側はさぞかし歯痒かったのではなかろうかと想像します…。

            #てゆーかnewInstanceはライブラリレベルの単純ミスでもあるなあ。
            #Method#invokeみたいに引数を配列かなんかで渡すことにすれば良かったのになあ…
            親コメント
        • by visha (779) on 2002年02月15日 11時46分 (#63053) 日記

          別に擁護するほどの義理も思い入れもないんだけど。

          僕がJavaで駄目だと思うところはまず実行速度です。 JITの技術がありますが本質的な解決策では無いと思います。 しかもテキスト処理なんかはJITを使ってもAwkよりもPerlよりも遅い。

          必要な時にプロセスとして起動するような用途には当然向かないですよ? PerlはともかくAWKを並べてるところを見ると、「テキスト処理」ってUNIXのフィルタプログラム的な使い方を想定してるんじゃないでしょうか?

          Javaのソフトウェアをまともに使おうと思ったら、JavaVMは基本的に立ち上げっぱなし、その中でサービスを回して行くような方法しか今のところはないでしょう。それが、いわゆるJ2EEの考え方(のごく一面)ですね。

          だからこそ、JavaOSなんて考え方があったんでしょう。要は適材適所ってこと。

          親コメント
          • Re:Javaの必要性 (スコア:2, 参考になる)

            by G7 (3009) on 2002年02月15日 14時47分 (#63150)
            >必要な時にプロセスとして起動するような用途には当然向かないですよ?

            それは実感しますね。
            jvmの起動はやっぱり遅い。一方でいったん上がれば遅さが気になることは案外(?)多くない。

            複数の関連ある処理(の単位:OOPとそれ以外を比較するときにはこの辺が曖昧な言い方になっちゃいますが)を
            繋ぎあわせて使うという状況においては、unixのプロセスモデルより、java(に限らないけど)の
            Object単位のモデルのほうが、メリットが多いことが多いです。プロセスだと処理単位間の「壁」が高すぎ。

            それがまさに、CGIに対するservlet、makeに対するant、のメリットになっているという触れ込み(^^;。

            オフトピだけどant。make時に必要な複数の処理を同一プロセス(^^;でやってくれるのは
            たしかに魅力的なんだけど、もう一歩欲しいです。
            もしコンパイルが「終わって」も尚プロセスが残っていてくれたら、そして
            次のコンパイルにそれを使い回せたら、きっと更に速くなるだろうに、と。
            親コメント
          • by loginPenguin (7275) on 2002年02月15日 12時07分 (#63066)
            実のあるコメントありがとうございます。
            AWK、Perlを例に挙げたのはUNIXのフィルタプログラム的な使い方を想定してるわけではなく、とにかく遅いって言いたかっただけです。
            僕自身AwkやPerlよりも遅いと知ったときに非常に驚いたもので。
            「ある特定の用途にはJavaが非常に有用だ」
            というのは分かります。
            ただ、言語として総合的な観点から見た場合に魅力的な言語だと僕は思えません。
            しかし、Java信者ってすごく熱烈的ですよね?
            いったいどこに魅力を感じるのかというのが僕にとって興味あることなのです。
            親コメント
            • by himuro (547) on 2002年02月15日 12時16分 (#63072) ホームページ
              私もみなさんの意見を聞いてちょっと安心しました。

              "あーんなに遅いのに、みんな平気で使っているんだろうか?"

              って Java を使うときはいつも思っていたのですが、
              やっぱしそのように思っている同士がいたということで。

              Java の情報って、"けっこう速いですよ、いいですよ"
              って思わせる情報ばっかりが見つかって,
              "Java ダメじゃん.." って情報はあまり書いている人が
              多くないんですよね。

              欠点を述べるのって、結構重要だと思うのですよ。
              だって、どのような時に Java を使えばいいかという
              判断材料としては非常に有効ですから。

              いろいろ勉強になりました。
              親コメント
            • 先に挙がった不満点って「言語」じゃなくて「実行系」の話ばかりだと思うんだけど。
              もちろん実行系の制約ってのは、Javaの思想に起因してるのだろうけど、それは言語としての評価とはちょっと違うように思います。
              確かに、環境(言語と実行系を両方含めた話)としてのJavaは、あれこれ不満が多いですけど、ね。
              親コメント
              • いや、言葉の使い方が気になった、というだけなのです。個人的に、「(プログラム)言語の善し悪し」と言ったら、言語仕様のことと考えてしまうので。だから、「実際の実行系とは別でしょ」と。
                もちろん「言語」という言葉をそんな厳密に使ってるわけじゃないのはわかってるのです。けど、つい血が騒ぐというかなんというか。
                親コメント
            • by iwa (2980) on 2002年02月15日 18時06分 (#63223)

              awkやperlに比べて不利な点は、 「実行速度が遅い」ことではなく、「起動が遅い」ことではないでしょうか。

              一回走り出したら、十分な速度を持っているよーな気が。

              # emacsみたいにdumpして(比較的)高速に起動するということはできないのだろうか…。
              親コメント
              • by G7 (3009) on 2002年02月17日 1時34分 (#63651)
                >emacsみたいにdumpして(比較的)高速に起動

                instance(ってのかな)をメモリからファイルに永続化しといて
                それを後で読みなおして再現する、って奴ですよね。
                smalltalkだとImageFileとか言うんだっけか?

                javaでは、class fileを束ねる(束ねるだけだ)ためにはjarフォーマットが有りますが、
                そういやinstanceを束ねる標準フォーマットってのは作られなかったですよね。
                objectを直列化する仕組とかは有るけど、それの最初の応用例(^^;としての
                永続標準フォーマットってのは…

                たしかに、勿体ない話です。
                親コメント
            • by G7 (3009) on 2002年02月17日 1時04分 (#63643)
              >とにかく遅いって言いたかっただけ

              どういうときにどう遅いか?という話しかたをしないと、
              それこそ不毛な議論になっちゃうのでわ(^^;。
              さすがにどんな状況でも必ず遅いというわけではないのですから、
              「とにかく」では大雑把すぎです。

              ま、今ここでベンチマークやって具体的な結論を出せ、とまでは迫りませんが、
              今じゃなく実際になんらかの選択をする場面になったときには、
              「とにかく」じゃなくてもう少し情報量のある思考を、してください。
              そのほうが世のためですから。

              #前述のように、状況を「区別せず差別する」のは不味いわけです(^^;
              #どういう状況なのか?を、しっかりと"見る"必要は、ありますね。

              >「ある特定の用途にはJavaが非常に有用だ」
              >というのは分かります。
              >ただ、言語として総合的な観点から見た場合に魅力的な言語だと僕は思えません。

              総合といっても、(あなたが意図するところの)総合とは何処から何処までを指すのか?ってのが問題でしょうね。

              たとえばunixフィルタ的に使う限り常(^^;に遅いであろうわけですが、
              それは総合というよりもunixという特殊な(^^;状況における特殊解であるわけです。
              そういう特殊な状況では、不運にも(^^;javaはperlより遅くなってしまう、と。

              ならば、そういう状況に出逢ったとき、じゃあjavaをやめる、という選択肢と同じくらいに
              じゃあunixをやめる、という選択肢だって、ひょっとしたら考慮に値するかも知れない。

              普遍であるかのように思っていた状況が、実は結構ローカルなものである、ってことは、よくあるようです。
              どうか、お見知り置きを。

              それはそれとして、俺も、javaにゃ納得できない面が結構あります(^^;;;;
              親コメント
        • by moonbear (4602) on 2002年02月15日 11時55分 (#63059)
          実行速度の不満についてはそのうち解決するでしょう.静的かつ強い型付けの言語なので,PerlやRubyと比べて原理的に遅くなる理由はありません.

          不要なオブジェクトへの活きた参照をいつまでもかかえてしまうようなコーディングをしてしまうと,長時間運用後にVMが落ちることがあります.確かに見つけにくいバグではありますが,GCがない場合のメモリリークはそれ以上に見つけにくいバグですし,何よりも開放してしまったメモリ領域を触る危険性がない方が安心して使えるのではないでしょうか.
          親コメント
          • by tix (7637) on 2002年02月15日 12時48分 (#63093) ホームページ
            Java はダウンキャストのときに動的型チェックをする必要があるので、 statically strongly typed ではなく dynamically strongly typed だと思います。

            それともぼくが用語の定義を間違えているのかな。このあたりの概念、感覚的にしか把握していません。

            Perl より遅くなる理由はない、というのは理解できますが。

            // ただ、 Perl と実行速度を比較されているのは Java がなんか気の毒。
            --
            鵜呑みにしてみる?
            親コメント
        • Re:Javaの必要性 (スコア:2, 参考になる)

          by mishima (737) on 2002年02月15日 12時13分 (#63069) ホームページ 日記
          > GCを利点として挙げる人がいますが、それも僕はどうかと思っています。
          > GCがあるためにむちゃくちゃなプログラムでもある程度動いてしまいます。
          > 1時間ぐらいだったら動くけど長時間動かしているとVMが落ちることがありますし、その時のバグを見つけるのが非常に大変です。

          C だって「解放忘れ」なら同じ現象が起こるでしょー。

          Java は free を呼ぶ替わりに使わなくなったポインタに逐一 null を入れろ、ってだけ。
          むしろ、C では使われていないポインタに NULL 以外の値が
          入っていることがあって、そっちの方が危ないと思うのだがどうか。

          #ま、C だって boehm GC みたいなのがあるけどね。
          --
          # mishimaは本田透先生を熱烈に応援しています
          親コメント
          • Re:Javaの必要性 (スコア:2, 参考になる)

            by k6p (7828) on 2002年02月16日 3時01分 (#63418)
            C だって「解放忘れ」なら同じ現象が起こるでしょー。
            少し違うと思います。
            Cで動的に確保されたメモリブロックは、明示的に解放しない限り、(少なくとも)そのプロセスの生存中は回収されないのに対して、Javaの場合は、他から参照されなくなったオブジェクトは、ガベージコレクタによって自動的に回収されます。(そもそも、解放するという操作自体がない)
            また、
            Java は free を呼ぶ替わりに使わなくなったポインタに逐一 null を入れろ、ってだけ。
            これも、ガベージコレクタがオブジェクトを回収する際の「ヒント」を与えるために使われるテクニックであって、必ずしなければならない、というものではありません。(スコープを外れ、どこからも参照されていなければ、回収される)
            # 「ポインタ」という用語も不適切かと。

            (未確認ですが、ガベージコレクタの性能の向上で、そういったテクニックをする必要もなくなってきた、というような話もあるらしいです)
            親コメント
            • ちょっとスレッドの流れを読み直して頂きたいが。

              > > C だって「解放忘れ」なら同じ現象が起こるでしょー。
              > 少し違うと思います。
              > Cで動的に確保されたメモリブロックは、明示的に解放しない限り、(少なくとも)そのプロセスの生存中は回収されないのに対して、Javaの場合は、他から参照されなくなったオブジェクトは、ガベージコレクタによって自動的に回収されます。(そもそも、解放するという操作自体がない)

              ?よく意味が分からん。
              短時間では問題はないが、長時間動かすとVMが落ちるようなプログラム、
              というのは明らかにメモリを食い潰しているのであって、
              C でこれと同じ状況は「解放忘れ」で簡単に起こる、というだけのことだろう。

              > > Java は free を呼ぶ替わりに使わなくなったポインタに逐一 null を入れろ、ってだけ。
              > これも、ガベージコレクタがオブジェクトを回収する際の「ヒント」を与えるために使われるテクニックであって、必ずしなければならない、というものではありません。

              一般論ではもちろんそうだが、
              メモリ不足でVMが落ちる、なんて状況では必須だろう
              (そうでなければGCが回収しているはずなんだから)。

              #「ポインタ」は不適切だったな。すまん
              --
              # mishimaは本田透先生を熱烈に応援しています
              親コメント
              • by k6p (7828) on 2002年02月16日 17時43分 (#63557)
                C でこれと同じ状況は「解放忘れ」で簡単に起こる、というだけのことだろう。
                Javaのオブジェクト解放漏れで起こるのと同じ状況がCのメモリブロック解放忘れで起こるといっていたのですね。たしかに、状況そのものについてのコメントを、状況の起こるメカニズムについてのものと読み違いしていたようです。
                > > Java は free を呼ぶ替わりに使わなくなったポインタに逐一 null を入れろ、ってだけ。
                > これも、ガベージコレクタがオブジェクトを回収する際の「ヒント」を与えるために使われるテクニックであって、必ずしなければならない、というものではありません。

                一般論ではもちろんそうだが、
                メモリ不足でVMが落ちる、なんて状況では必須だろう
                (そうでなければGCが回収しているはずなんだから)。
                オブジェクト同士の意図しない循環参照などを断ち切る(その結果ガベージコレクタが回収できるようにする)ためにnullを代入すべきだということであれば同意します。
                が、Cでfreeを呼ぶ代わりに、Javaではとにかくnullを代入すればよいという風に読めたので。それだと、Cのメモリ管理のやり方とJavaのやり方を混同されかねないと思いました。
                結果的に同じことじゃないかといわれそうですが、解放が(プログラムの指示によって)能動的に行われるか、(VMの働きによって、プログラム側から見ると)受動的に行われるかという概念の違いは大きいのではないかと思います。
                親コメント
        • GCの必要性 (スコア:2, 参考になる)

          by goodlife (5595) on 2002年02月15日 12時34分 (#63086) 日記
          GCを利点として挙げる人がいますが、それも僕はどうかと思っています。
          GCがあるためにむちゃくちゃなプログラムでもある程度動いてしまいます。
          GC を単にメモリリークを防ぐためのものと考えると大したありがたみはありませんが,メモリフラグメンテーションを防ぐためのものと考えれば,その恩恵は計り知れないと思います。

          C++ でマルチスレッドプログラムを書く時のメモリ管理の難しさといったら。まあ,気にしなくても動きますけど(皮肉なことに)。

          親コメント
          • by G7 (3009) on 2002年02月15日 14時57分 (#63154)
            >GC を単にメモリリークを防ぐためのものと考えると大したありがたみはありませんが,メモリフラグメン
            >テーションを防ぐためのものと考えれば,その恩恵は計り知れないと思います。

            え?

            http://www.is.s.u-tokyo.ac.jp/~vu/jugyo/processor/process/soft/compilerresume/gc/gc.html
            >Copying GCの興味深い性質は、コピーするときにオブジェクトの空きをつめるため、fragmentationが発生しないということである。

            によると、フラグメンテーションを無くす機能(つーか嬉しい副作用?)を期待できるかどうかは
            GCのアルゴリズム次第であって、GC一般の性質ではない、と読めますけど?

            それとも、その副作用のあるGCしか使う予定が無い、言い換えれば
            使おうとしている処理系のGCがお望みのアルゴリズムであることが既に判っている、
            という状況なのでしょうか?

            そりゃそうと、メモリリークが無くなるってのについては、有り難いと思いますよ。

            1:unixプロセスモデル配下の短寿命プロセスならば、最悪でも「間もなく」OSがメモリを回収してくれる
            ので有り難味は少ないかもだが、そうでないならそれ以外の管理が必要になる。

            2:開放タイミングを決定するのが結構面倒なプログラミング形態も、ある。

            ので、あーゆーものは、(プログラマの技量次第というよりも(笑))状況次第で、凄く欲しくなると思うんですが。
            親コメント
            • by nasb (3002) on 2002年02月15日 15時26分 (#63162) 日記
              > > メモリフラグメンテーションを防ぐためのものと考えれば,その恩恵は計り知れないと思います。

              (中略)

              > フラグメンテーションを無くす機能(つーか嬉しい副作用?)を期待できるか
              > どうかは GCのアルゴリズム次第であって、GC一般の性質ではない、と読め
              > ますけど?

              元コメントは、フラグメンテーションがプログラマに不可視になることを言いたかったんだと、愚考します。

              # 違ったらどうしよう。^_^;

              新しいjavaコマンド(VM)は並列GCを実装していますね。どんなアルゴリズムを使ってるんでしょうか。興味があります。106CPUでもちゃんと動いてくれるでしょうか。:-)
              親コメント
            • > によると、フラグメンテーションを無くす機能(つーか嬉しい副作用?)を期待できるかどうかは
              > GCのアルゴリズム次第であって、GC一般の性質ではない、と読めますけど?

              GC がどのようなアルゴリズムで行われるにせよ、compaction は
              行われてるのではないでしょうか? compaction されるというこ
              とは、その時点でフラグメンテーションも解消される、ということ
              ですよね?違う?

              Java の Heap に関しては、激しくオブジェクトの生成/回収を
              繰り返してもフラグメンテーションによって新規オブジェクトが
              生成できない、とゆー事態には陥ったことがないため漠然とそう
              思ってたんですけど…。

              UNIX のようにプロセスを起こすコストが結構大きい OS がサーバ
              で主流な昨今、比較的容易にお行儀のいい長寿命プロセスを作成
              出来る Java は非常に有用だと思います。
              --
              Only Jav^Hpanese available :-)
              親コメント
              • by nasb (3002) on 2002年02月15日 20時31分 (#63293) 日記
                > GC がどのようなアルゴリズムで行われるにせよ、compaction は 行われて るのではないでしょうか?

                いいえ。G7さんが紹介してくれましたURLがよい資料なので、詳しくは そちらを見てください。ここでは簡単に言いますと、GCは古典的には、

                1. Reference Count (被参照数が0になったオブジェクトを回収)
                2. Mark & Sweep (生きているオブジェクトにマークをつけ、最終的にマークがつかなかったオブジェクトを回収)
                3. Copying (生きているオブジェクトを別の領域に詰めながらコピーして、元の領域をまとめて回収)
                の3種類がありまして、他の多くのバリエーションもこれらの何らかの発展形 になってます。このうち、1.と2.はcompactionしません。
                親コメント
              • by brake-handle (5065) on 2002年02月16日 16時18分 (#63542)

                確認ですが、

                Java の Heap に関しては、激しくオブジェクトの生成/回収を繰り返してもフラグメンテーションによって新規オブジェクトが生成できない、とゆー事態には陥ったことがない

                というのは、異なるサイズのオブジェクトを生成、回収した場合ですか? というのは、同じサイズばっかりだったらそもそも空きメモリの断片化は問題にならないはずなので。

                ちなみに、アドレス空間を長持ちさせると(Unixのkernelはその典型)、オブジェクトの生成にともなう再初期化が大きなオーバヘッドになってきます。これは、オブジェクトが不要になった時、その中身はオブジェクトが初めて生成された時とほぼ同じになっていることが多いためです(eg 連結リストの要素の場合、前後へのポインタは初期化時も解放時もnull)。

                これを解決する方法として、解放されたばかりのオブジェクトを直ちに再利用に回すことが挙げられます。Solarisのslab allocatorはこの方法を用い、オブジェクトの割り当てと初期化時間を最大で8割減らすことができています。Javaでもこういうことはやってるんでしょうか?

                親コメント
              • > GC がどのようなアルゴリズムで行われるにせよ、compaction は
                > 行われてるのではないでしょうか? compaction されるというこ
                > とは、その時点でフラグメンテーションも解消される、ということ
                > ですよね?違う?
                > Java の Heap に関しては、激しくオブジェクトの生成/回収を
                > 繰り返してもフラグメンテーションによって新規オブジェクトが
                > 生成できない、とゆー事態には陥ったことがないため漠然とそう
                > 思ってたんですけど…。

                私も空きメモリの合計が 要求メモリサイズを上回っているうちから
                out of memory を出すへたれな JavaVM は見たことのないです。

                ただ、GC が行われた後はフラグメンテーションが解決されているか
                と言うと必ずしもそうではないと思います。
                例えば、普段の GC はフラグメンテーションの解決を行わないけど、
                断片化されない最大の空き領域のサイズが要求サイズを満たさない
                場合にはしょうがないので、フラグメンテーションを解決する GC
                を改めて起こすという方法があります。

                特に他の Java スレッドを止めずに GC スレッドがメモリを回収
                して回る On-the-flay 型 GC は、生きているオブジェクトの位置
                をむやみに動かせませんし、、、
                --
                コンタミは発見の母
                親コメント
              • > このうち、1.と2.は compactionしません。

                実際に compaction を行わない GC 実装が存在することはもちろ
                ん知っていますし、JavaVM Spec. が Heap 管理については 100%
                実装者の裁量に任せている、ことも分かっていますが、しかし、
                ご存じの通り Java にはポインタがありませんから、C でのよう
                にプログラム側でフラグメンテーションに対処することが非常に難しく、
                となると、まっとうな実装者ならばフラグメンテーションが起こら
                ないように GC を設計するのではないか、という予想のもと、こと
                現代的な実装の JavaVM に関していうなら、G7 さんの書込みでい
                うところの「それとも、その副作用のあるGCしか使う予定が無い、
                言い換えれば使おうとしている処理系のGCがお望みのアルゴリズム
                であることが既に判っている、という状況」といえるのではないか、
                前の書込みに補足すれば「GC がどのようなアルゴリズムで行われ
                るにせよ、JavaVM においては常に compaction は行われている
                と考えていいのではないでしょうか?」というのが趣旨です。

                #組み込み系まで含めると必ずしも真ではないかもしれませんが、
                #J2SE 以上の各社の実装を見ているとそう言えるのではないかと。

                J2SE 以上の実装では半ば常識的なことながら、JavaVM Spec. で
                はっきり規定された仕様ではない、という点を、G7 さんは暗に指
                摘されていたのかな…?
                --
                Only Jav^Hpanese available :-)
                親コメント
              • by G7 (3009) on 2002年02月16日 13時46分 (#63516)
                >ご存じの通り Java にはポインタがありませんから、C でのよう
                >にプログラム側でフラグメンテーションに対処することが非常に難しく、

                ああ。メモリプールというかmallocに相当するものを自作するという話題ですか。
                たしかにjavaでは何処をどういじってもソレっぽいことは出来ないですね。

                >現代的な実装の JavaVM に関していうなら、G7 さんの書込みでい
                >うところの「それとも、その副作用のあるGCしか使う予定が無い、
                >言い換えれば使おうとしている処理系のGCがお望みのアルゴリズム
                >であることが既に判っている、という状況」といえるのではないか、

                それを称して「現代的」と呼ぶんでしょうか?>識者諸兄
                俺は知らないんですが。

                >JavaVM においては常に compaction は行われている

                そこでいう「JavaVM」がどこまでを指すか?に拠るでしょうね。

                Sunなりなんなりの1つ(^^;の実装について語りたいなら、
                メーカーに質問するとか、気に入らないなら(金を出して)変更を迫るとか、
                いろんな手が有り得そうです。

                でも、KaffeやWavaみたいな偽Java(^^;とか、あるいは各種(?)小型組み込み向けJavaとか、も
                含めて考えると、その期待が満たされてるかどうかは、また違う話になるわけですよね。

                >#J2SE 以上の各社の実装を見ているとそう言えるのではないかと。

                上に書きましたが、Kaffeって、どう捉えたらいいんでしょうね?(^^;

                J2SEとは…あ、どうせ言えないのか。
                Java1.2相当にも、まだなってないんでしたっけかあれ?
                … http://www.kaffe.org/ … あ。まだ1.1相当かあ。
                親コメント
              • nasb さん あるいは元資料の人は compaction という言葉を「フラグメンテーションを取る処理」ほどの
                意味で使っていると思うのですが、
                厳密に言うと GC の世界では compaction は in place(同じ領域内で)にオブジェクトをつめる処理を指すので、
                3. の Copying GC も compaction はやらないと思います。
                --
                コンタミは発見の母
                親コメント
              • by G7 (3009) on 2002年02月17日 2時18分 (#63659)
                >解放されたばかりのオブジェクトを直ちに再利用に回すことが挙げられます。Solarisのslab allocatorはこの方法を用い、オブジェクトの割り当てと初期化時間を最大で8割減らすことができています。Javaでもこういうことはやってるんでしょうか?

                それ、もしかして、解放された領域を、「同じ種類」ごとに
                別々のフリーリストにぶら下げたりする、んでしょうか?

                だとしたら、種類という概念がクラスのおかげ(乱暴な言いかただが)で
                C的世界よりずっとはっきりしているoop処理系においては、
                より旨くやれるんではないでしょうか?

                つまり卑近に言えば、多くてもせいぜいClassの数と同じ数のフリーリストを作ればいい、
                リストをDictionaryにぶらさげて、リストをDictの中で選択するためのキーはjava.lang.Classである、
                みたいな感じで…?(^^;

                #そういう意味では、所詮(ごめん)C世界でしかないunix系カーネルとは
                #いっしょにならんというか、もっともっとエレガントにやれるというか、ではないかなあ。
                親コメント
              • by brake-handle (5065) on 2002年02月17日 20時32分 (#63701)
                それ、もしかして、解放された領域を、「同じ種類」ごとに別々のフリーリストにぶら下げたりする、んでしょうか?

                厳密には、page level allocator(つまりvirtual memory)から切り出してきた、free objectのcacheに放り込みます。このcacheはper object typeです。

                だとしたら、種類という概念がクラスのおかげ(乱暴な言いかただが)でC的世界よりずっとはっきりしているoop処理系においては、より旨くやれるんではないでしょうか?

                それはなんともいえません。Uresh Vahaliaは著書Unix Internals: The New Frontiers [amazon.com]の中で、以下のようなslab allocatorの欠点を指摘しています(以下は邦訳より)。

                スラブ・アロケータの1つの欠点は、それぞれのオブジェクトの種類に対してことなるキャッシュを持つことに起因する、管理上のオーバヘッドである。
                (中略)
                (キャッシュに含まれる)要素が少なく、あまり使用されないキャッシュの場合のオーバヘッドは、しばしば、無視できないものである。

                となると、cacheを使うか否かを決める問題が生じます。Solarisの場合、私が本や実装を(誰か1994年夏のUsenix [usenix.org]予稿集持ってませんか?)見た限りでは、cacheを使うか否かはobject type毎にhardcodeされている(すなわち人間が決めている)ようです。Unix kernelならこれでも何とかなりますが、個々のプログラムを支える枠組み、すなわち言語処理系やruntime libraryなどの場合は機械的に決めないと使いものにならないでしょう。Solarisがこれをやっていないということは、機械的な決定は難しいということでしょうか。

                親コメント
              • SUN の JavaVM しか知らないのですが、現行のほとんどのJVM は
                空き領域の管理をフリーリストではなく、下から順番に詰めて
                使って行くヒープポインタ(というのか?)で管理していると思われます。
                ヒープポインタを確保したサイズ分増やすだけなので総合的に見てスピードが速いのです。

                少なくも SUN JDK1.3、1.4 はこの方式です。
                ClassiVM はインスタンスを指すハンドラとハンドラの実体
                に分かれていて、ハンドラ領域はフリーリスト管理で、実体を
                格納するヒープ領域はヒープポインタ管理です。
                # ハンドラは全部同じ大きさ。
                --
                コンタミは発見の母
                親コメント
              • > それを称して「現代的」と呼ぶんでしょうか?>識者諸兄
                > 俺は知らないんですが。

                compaction をやることが現代的な GC だとは思いません。

                長い GC の歴史の中である程度 よい GC の条件が見えてきています。
                非並列 GC の場合に限ると以下の 4点ぐらいを押さえた GC が現代的
                な GC ではないでしょうか?

                1. オブジェクトの寿命を意識すること

                    オブジェクトには生成されたけど一度も使われずに終わる
                    単寿命なやつから VM が終わるまで居続ける長生きなオブ
                    ジェクトまで寿命に差があります。
                    現代の GC はこの性質を旨く使う事が何より求められています。

                2. キャッシュを意識すること

                    現代的なプロセッサはキャッシュの性能におんぶでだっこ。
                    GC といえどもキャッシュミスヒットを避ける努力が必要です。
                   
                3. 排他制御は最小に
                   
                    fetch & add や compare & swap のようなアトミック命令は
                    最初にするのが吉です。
                    OS の同期オブジェクトの極力使わないことが求められます。
                   
                4. 処理は短く
                   
                    それぞれの操作(例えば 1回の new)にかかる時間を減らすことも
                    重要です。
                    それ以外にも stop the world を掛けてから本当にすべてのスレッド
                    が止まって GC がはじまるまでのタイムラグだとかがあります。
                --
                コンタミは発見の母
                親コメント
          • Re:GCの必要性 (スコア:1, 参考になる)

            by Anonymous Coward on 2002年02月15日 18時30分 (#63232)
            よく理解できません。

            > GCを利点として挙げる人がいますが、それも僕はどうかと思っています。
            > GCがあるためにむちゃくちゃなプログラムでもある程度動いてしまいます。

            これは、null なのに使おうとしたって事で、C++とJavaに差は余り無い気がします。
            GCとは関係ないのでは?

            > 1時間ぐらいだったら動くけど長時間動かしているとVMが落ちることがありますし、その時のバグを見つけるのが非常に大変です。

            これは、メモリリークしているということだとすると、GCのおかげで、それは無くなるんではないでしょうか?
            メモリが無くなっているとしても、直接には、別の原因でVMが落ちているのでは無いでしょうか?

            GCのおかげで、deleteを書かなくて良いとか、ポインタ変数を、参照出来なくなっても良いとか言うのはかなり良いと思います。

            それと、APIまでJava言語に含まれているおかげで、スレッドも大抵のJavaの本で触れられているし、C++に比べ簡単になること自体で本の内容がそれを埋める分だけ色々増えているのは良いです。
            親コメント
            • by k6p (7828) on 2002年02月16日 2時28分 (#63411)
              # 親コメント [srad.jp]の位置がおかしいと思います(goodlifeさんのコメント [srad.jp]に対してではなく、loginPenguinさんのコメント [srad.jp]に対するものですよね?)が、それはともかく、
              > GCがあるためにむちゃくちゃなプログラムでもある程度動いてしまいます。

              これは、null なのに使おうとしたって事で、C++とJavaに差は余り無い気がします。
              GCとは関係ないのでは?
              関係はあると思います。
              ガベージコレクタがオブジェクトの回収をやってくれるおかげで、メモリリークが顕在化しにくくなったため、オブジェクトの管理がいい加減なプログラムでも、それなりに動いてしまう、という話では?
              で、その結果、真綿で首を絞めるように、回収されない(できない)オブジェクトがじわじわと蓄積して、
              > 1時間ぐらいだったら動くけど長時間動かしているとVMが落ちることがありますし、その時のバグを見つけるのが非常に大変です。
              となると。

              「Java(の)メモリリーク」などと呼ばれるようです。

              # 私自身は「だからGCに利点はそれほどない」とは思いませんが。
              親コメント
        • by hatoku (1188) on 2002年02月15日 12時50分 (#63095) 日記
          >次に移植性です。
          >Write Once Run Anywareとか言っていますがはっきり言って実現されて無いと思います。

           それはおっしゃる通りです。おれもなんだかんだ言って結局は、
          Windowsクライアントでソース書く->Unixのサーバー上にftpしてコンパイル
          なんてしたましたし(笑)今はサーバーもクライアントもlinuxだからその点楽。

          >移植性 + 速度
          >で考えるとCの方が上だと思っています。

          write once....は「コンパイル済みのバイナリコードがそのまま移植できる」ということだと思うのだけど。Cの移植性(ソースもってってコンパイルすればOK)とは別の話になると思いますが。

          ソースの移植性についても、#ifdef WIN32みたいなマネをする箇所がjavaならかなり減るのでは?、特にGUIについては。

          というか、javaにマクロは無いが<-おれにとってはこれがjavaの嫌なとこです(笑)

          それに、たとえば顧客にUNIX上で動くPGを納品するときに、ソースに#ifdef WIN32とか書いてあったらマズイ(笑)
          速度に関しては、たしかに遅いですね。GUIのアプリをまともに作る気分にはなれない。

          >最後にIDEです。
          >デバッグが難しいのにろくなIDEが無いために開発が非常に面倒です。

          xemacs + javac + jdbで開発してます(笑)
          #そいえばCもdbxでやってたな
          親コメント

犯人は巨人ファンでA型で眼鏡をかけている -- あるハッカー

処理中...