- PR -

サーブレットでページング処理

投稿者投稿内容
永井和彦
ぬし
会議室デビュー日: 2002/07/03
投稿数: 276
お住まい・勤務地: 東京都
投稿日時: 2002-09-20 18:15
永井%Javaは今春に始めたばかり、です。

引用:

>むしろ、同期を自分でとらざるをえない ArrayList/HashMap を使って
>同期のし忘れによるもっともデバグしにくい謎の挙動が出てくるよりかは、
>パフォーマンスを少々犠牲にしてでも、安全のためには Vector/Hashtable の
>ほうがいいと思っているのですが。
これは大間違い.少々どころじゃありません.
#特にサーバーサイドJavaでは....



同時利用者数によって、リニア(それ以上の場合も?)にレスポンスタイムが
悪化するというお話でしょうか。確かにそれだとぞっとしない状況ではあります。
#しかも、一旦溜まりだすとその傾向が加速して一気に爆発する?

ちらっと検索をかけてみると、ここでも強く警告されていました。
http://www.netgene.co.jp/java/docs/javaPressVol19.html#14

かくいう私なんかも、まだ頭が逐次処理ですので、今まではあまり
意識したことはなかったのですけれど。<Vector

マルチスレッドな場面ではパフォーマンスの問題から使えない、シングルスレッドな
場面では別に同期問題は発生しないから必要ないということでしょうか?<Vector
……そうすると、Vectorのことは忘れた方がいいということになりそうですが。

未記入
ぬし
会議室デビュー日: 2002/03/28
投稿数: 255
投稿日時: 2002-09-20 21:32
>同時利用者数によって、リニア(それ以上の場合も?)にレスポンスタイムが
>悪化するというお話でしょうか。確かにそれだとぞっとしない状況ではあります。
最悪ではデッドロックを起こします.

デッドロックを起こさない場合でも,「それ以上」になりえます.
スケジューリングやコンテキストスイッチばかりで,スレッドが
ほとんど全く走らない時などにこうなります.

上り下り合わせて100車線の道路のうち,99車線が工事中で通行止めという
状況を想像してもらえばわかりますよね.これが1000車線になったり,
1万車線になったりすれば,どうなるか.....

>ちらっと検索をかけてみると、ここでも強く警告されていました。
>http://www.netgene.co.jp/java/docs/javaPressVol19.html#14
またマニアックなページを...f(^^;
#いや,悪いわけじゃないんだけど...

>マルチスレッドな場面ではパフォーマンスの問題から使えない、シングルスレッドな
>場面では別に同期問題は発生しないから必要ないということでしょうか?<Vector
まさにその通りです.
#始めたばかりでこの結論に到達できるとは,意外とセンスはあるのでは?

>……そうすると、Vectorのことは忘れた方がいいということになりそうですが。
おそらくは上記の理由により,

VectorはJava2以降は,既にレガシー(時代遅れの遺物)コレクションクラス
(集合を扱うクラス)です.これははっきりと明記されています.「推奨されない」
クラス扱いになっていないのは,既に幅広く使われているために,突然削除すると
影響が大きすぎると判断されたためのようです.

ただし,レベルの低い入門書の中には,まだJava2に対応しておらずVectorを
「基本的で重要なクラス」として扱っているものもあるようです.やはり
「プログラミング言語Java 第三版」のような良書を手元に置いておくことは
レベルアップのためには必要でしょう.
amnaky
ベテラン
会議室デビュー日: 2002/09/13
投稿数: 75
お住まい・勤務地: 東京
投稿日時: 2002-09-21 01:04
表題と話題が離れているので気がひけますが、
興味がある話題なので。

ArrayListとVectorをソースで見比べてみると、
add()やset()など、synchronizedがついているかどうか
という以外ほとんど差がないんですよね。
その差が大きいと。

Servletをやってて、Servletってマルチスレッドプログラミング
してることになるんだと知ったのは白状するとわりと最近です。
マルチスレッドにともなう問題については基礎として誰もが
知っておくべきことなんだと目から鱗が落ちました。

ところで、Vectorなどレガシーコレクションクラスについて、

>シングルスレッドな場面では別に同期問題は発生しないから必要ない

という点はいいと思います。
無用なsynchronized句がいい影響を与えるわけはありません。

しかし、

>マルチスレッドな場面ではパフォーマンスの問題から使えない

という点に対して、素朴な疑問がうかびました。
私はそういう経験はありませんが、例えば複数のスレッドが非同期に
アクセスするVectorなりArrayListがあったとして、
Vectorならsynchronizedなのでそのままadd等できる、
ArrayListだったらunsynchronizedなので
自分でスレッドセーフにするために排他制御しなければならない。
とすると、そこに生じるパフォーマンスの差はそんなに大きいのだろうか、
というものです。
少なくとも、「使えない」とまで私は断言できません。

日ごろ漠然と考えてたんです。
実験してみりゃいいじゃんという話ではありますが、
皆さんの意見はどうでしょうか。
しょむ
ぬし
会議室デビュー日: 2001/09/06
投稿数: 430
投稿日時: 2002-09-21 09:39
まとまった内容になりそうな気もするので、別スレたてました。

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2182&forum=12&0
みやも
ベテラン
会議室デビュー日: 2002/04/22
投稿数: 74
投稿日時: 2002-09-22 18:10
コレクションの話はおいといて、
私も前から、うまいページ処理の方法ないかなぁ、って思ってみました。

これだけ幅広くどこでも使われているような処理(Googleやここの会議室でも)なので、
既存のコンポーネントやタグライブラリあってもよさそうなものですが、
どなたかご存知ありません?

表示件数や、キャッシュにレコードをもつか、毎回DBに問い合わすかとかは、
設定(か引数)で出来るようなやつ。。。


余談ですが、
検索件数の指定はOracleではROWIDを使った記憶があります。
でも昔の話なので、今はもっと便利な方法があるかも。
(株)ぽち
ぬし
会議室デビュー日: 2002/09/10
投稿数: 376
投稿日時: 2002-09-25 14:09
こんにちわ。

途中話しが少しズレてきていますが、主題のページング処理について。
わたしの場合は以下のような感じでやってす。

例えば1ページに10件ずつ表示する場合
Servlet Bean JSP のMVCでやってますが簡単に言うと、

検索ボタン押下
→ Serlvlet(bean生成、DB接続)
→ DB(検索結果取得)
→ Bean(全検索結果格納、1〜10件分を別配列に格納)
→ JSP(beanから10件分の配列取得)

次へボタン押下
→ Servlet
→ bean(11〜20件分を配列に格納しなおし)
→JSP(beanから10件分の配列取得)


こんな感じですね。前ページ、次ページ表示処理は全く同じ処理です(引数違うだけ)
実際はbeanの中で全ページ数、現在のページ数、次へボタン表示フラグ、
前へボタン表示フラグ、検索ヒット数、など色々計算、表示に必要な
パラメータは持たせてます。


僕のやり方だと検索結果をすべてメモリに格納している状態なので
「次へ」「前へ」処理にかかる時間は一定ですみます。
index指定でデータをひっこぬいてくるだけなので。

しかし、その分メモリを食います・・。

開発対象のユーザ数などにもよりますが
ハイスペックなマシンを用意する、もしくは検索ヒット数に制限をかけるか
などの必要があると思います。

僕はResultSetでDBから持ってきたものをArrayListに変換しています。
ArrayListの中身はObject[]です。

Object[]は基本的に全てStringです。

一度検索ヒット数3万件で、3枚のブラウザから検索かけた場合
tomcatがメモリあふれで落ちました・・。

調べてみたところ3万件のデータ、内部はObject[7]の状態だったのですが
30000×7=210000個のStringで約20MByte以上使用していました。

javaVMのデフォルトヒープサイズが64なので
20MByte超えが3つで64Mを超えたわけです。

このように内部にデータを持つと非常にメモリ消費が大きいです。
僕のつくりが悪いと言えばそれまでですが・・。

であれば毎回10件分のデータをDBアクセスで取得する方がいいのかもしれません。
場合によりきりかな?
まりり
ぬし
会議室デビュー日: 2001/12/05
投稿数: 329
投稿日時: 2002-09-25 16:38
(株)ぽちさんはメモリのことだけ気にしていますが、もう一点追加。

昨今のWebアプリはWebアプリケーションサーバとDBサーバが別のマシンで
あることが良くあると思います。
こういう場合、JSP/ServletなどからDBサーバへのアクセスでは
ネットワークがボトルネックになったりします。

JDBCドライバの実装にもよるでしょうが、実際に表示に利用するのは
10レコードなのに1000レコードを取ってきていてはレスポンスにも差が出ます。
最終的な取得レコードが10レコードだったとしても、1レコードずつ
取得していてはやっぱり遅くなります。

ネットワークというと帯域に目が行きがちですが、線は太くても
回数が多ければかなりのネックになるので気をつけたほうがよいでしょう。

スキルアップ/キャリアアップ(JOB@IT)