「java」タグアーカイブ

Javaで日付をゼロパディング/ゼロサプレスする方法まとめ

Javaで日付を扱う際、「月や日を2桁表示したい(01→1ではなく01のまま)」あるいは「逆にゼロを削除して自然な表示にしたい」という場面はよくあります。
この記事では、**ゼロパディング(ゼロ埋め)ゼロサプレス(ゼロ削除)**の両方を、実際のコード例を交えて分かりやすく解説します。


🧩 ゼロパディングとは?

ゼロパディング(zero padding)とは、数値や日付を指定桁数に揃えるために先頭に0を追加する処理のことです。
例えば「1」を「01」や「001」に整えることで、フォーマットがそろい、ソートや表示が安定します。

例:

元の値ゼロパディング後
101
505
1010

💡 String.format() を使ったゼロパディング

最もシンプルな方法は String.format() です。
桁数を %02d のように指定することで、足りない桁を自動的に0で埋めてくれます。

ポイント:

  • %02d → 2桁に揃えて左側を0埋め

  • %03d → 3桁に揃える(例:007 など)


📅 DateTimeFormatter を使ったゼロパディング

LocalDateLocalDateTimeを使う場合は、DateTimeFormatterの書式指定でゼロパディングが自動適用されます。

MMddといった2桁指定をすることで、常にゼロパディングされた日付が得られます。


🔻 ゼロサプレス(ゼロ削除)とは?

ゼロサプレス(zero suppress)とは、先頭の0を削除して自然な表示にすることを指します。
たとえば「01月」を「1月」に、「09日」を「9日」に整形するようなケースです。


🧮 getMonthValue()getDayOfMonth()を使う方法

LocalDateのメソッドを利用すれば、もともと整数型の値をそのまま出力できるため、ゼロサプレスした形で取得できます。


🧠 DecimalFormatで数値的に制御する

もし整数値を柔軟に扱いたい場合は、DecimalFormatを使うと便利です。

"00" → 常に2桁ゼロ埋め
"#" → 不要なゼロを省略(ゼロサプレス)


🔄 実用例:ゼロ埋め⇔ゼロ削除の切り替え

アプリケーションによっては、状況に応じて表示形式を切り替えたい場合もあります。


✅ まとめ

処理主な方法
ゼロパディングString.format("%02d") / DateTimeFormatter("MM")01, 05
ゼロサプレスgetMonthValue() / DecimalFormat("#")1, 5

ゼロパディングはフォーマットの統一やログ整形に便利で、ゼロサプレスは人が読む表示に適しています。
目的に応じてどちらを使うか選びましょう。

Javaメモリ管理の仕組み:ガーベジコレクションとヒープの基本

1. Javaのメモリ管理とは?

Javaはプログラマーが手動でメモリを解放しなくても良い言語です。
C・C++のように free() を使う必要はありません。

Javaでは、必要なくなったオブジェクトを自動で回収(解放)する仕組みが備わっています。
これを**ガーベジコレクション(Garbage Collection, GC)**と呼びます。

「解放漏れによるメモリリークが発生しづらい」
→ Javaが幅広く使われる理由の1つ


2. Javaのメモリ領域:ヒープとスタック

Javaアプリのメモリは主に次の2領域で管理されます。

領域役割特徴
ヒープ(Heap)オブジェクト、配列を格納GCの対象
スタック(Stack)メソッド実行中の変数・参照メソッド終了で自動解放

ヒープ領域の構造(JDK8以降)

領域内容
Young Generation新規オブジェクト領域(Eden、Survivor)
Old Generation長生きするオブジェクト領域

多くのオブジェクトはすぐ不要になる → Young に多く配置するのが効率的


3. ガーベジコレクションの動き

ガーベジコレクションは、参照されなくなったオブジェクトを検出・削除します。

処理の流れ

  1. オブジェクトを生成(ヒープに配置)

  2. 参照が切れる or 到達不能になる

  3. GCが不要オブジェクトを回収

GCアルゴリズム(代表)

名称特徴
Mark and Sweep到達可能オブジェクトに印を付け、残りを削除
Copying生きているオブジェクトを別領域に移動して残りを破棄
Generational GC世代(Young/Old)でGC動作を変える効率化方式

4. Javaの主要GC方式(JDKバージョン別)

GC機能特徴対象バージョン
Serial GCシングルスレッド、単純設計軽量アプリ
Parallel GC並列処理で高速デフォルト(Java8)
G1 GC大規模ヒープ向け、低停止時間Java9以降推奨
ZGC超低遅延GC、数百GB〜TB向けJava15以降
ShenandoahRedHat版、低遅延OpenJDK系

5. よくあるメモリ関連エラー

java.lang.OutOfMemoryError

ヒープ不足で発生
→ ヒープ拡張 or メモリリーク調査

StackOverflowError

再帰のしすぎなどでスタック溢れ

❌ メモリリーク

Javaでも発生します(例:Listにaddしっぱなし)


6. メモリ管理・GCチューニングのポイント

対策内容
不要な参照を早く消すローカル変数は小スコープ
大規模データは逐次処理巨大Listを避けIterator活用
WeakReference活用キャッシュ管理時に便利
GCログ・ツール利用-Xmx設定、VisualVM/FlightRecorder

JVMオプション例


7. まとめ

ポイント内容
Javaは自動メモリ管理ガーベジコレクションが解放処理
ヒープが主な領域Young/Old世代で効率化
GC方式は進化中G1GC・ZGCが主流
最適化の余地あり適切なコーディング+JVM設定

「自動だから安心」ではなく、仕組み理解でパフォーマンス向上!

Java:IllegalArgumentExceptionの意味と例外設計のベストプラクティス

Javaアプリケーション開発では「想定外の入力」に対して適切にエラーを発生させ、プログラムの異常動作を防ぐことが重要です。その際によく使用される例外のひとつが IllegalArgumentException です。

本記事では、IllegalArgumentException の意味、発生するケース、使い方の例、そして例外設計のベストプラクティスまで徹底解説します。


IllegalArgumentExceptionとは?

IllegalArgumentException とは、

メソッドに不正な引数(値)が渡された場合にスローされる実行時例外(RuntimeException)

です。

例えば、年齢を受け取るメソッドに 負の値 が渡された場合など、
「引数の値が意味を成していない」状態で使われます。


なぜIllegalArgumentExceptionを使うのか?

✔ 不適切な入力を早期に検知
✔ 異常な状態を防ぎ、予測可能な動作を保証
✔ 開発者や利用側に明確なフィードバック

特に、ライブラリ・APIの開発時には重要です。
「どんな値が許容されるのか?」を明確にすることで利用者のミスを防げます。


IllegalArgumentExceptionの基本例

✅ 正の値のみ受け付けるメソッド例

チェックポイント

  • 条件式で検証

  • 明確なメッセージで何が悪いか伝える


Integerチューター:標準APIにも見る例

Java標準APIも積極的にこの例外を使っています。

例:Thread#setPriority(int priority)

Java公式の一貫性ある設計に従うことで、コード品質が向上します。


IllegalArgumentException vs 他の例外

例外使う場面
IllegalArgumentException引数の値が不正
NullPointerException引数がnull不可なのにnull
IllegalStateExceptionオブジェクトの状態が不正
IOExceptionI/O操作中の問題

ポイント

  • 値がおかしい→IllegalArgumentException

  • 状態がおかしい→IllegalStateException


ベストプラクティス:例外設計ガイド

✅ 1. 早めにチェックする(Fail Fast)

異常はできるだけ早く発見しましょう。

✅ 2. メッセージで原因を明示

悪い例(NG)

何が悪いのか分からない…

✅ 3. Javadocで事前に仕様を明記

APIの信頼性が向上します。

✅ 4. nullチェックはObjects.requireNonNullで簡潔に


ユースケース:バリデーションロジックの整理方法

例外処理が肥大化しないよう、専用バリデータクラスを作るアプローチも有効です。

利用例:


まとめ

ポイント内容
例外名IllegalArgumentException
意味不正な引数が渡された
目的予期しない動作を防ぐ
コツFail Fast、明確なメッセージ、仕様明記

良い例外設計はコードの信頼性・保守性を大きく高めます。
実務でも積極的に活用していきましょう!

【Java初心者向け】staticって何?よくある質問を例付きで解説

Javaを学び始めると、最初に必ずと言っていいほど出てくるキーワードがstatic
でも、

  • staticって具体的に何をしているの?

  • いつ使うべき?

  • staticをつけないとどうなるの?

という疑問を持つ方が多いです。

この記事では、できるだけ分かりやすくstaticの意味や使いどころを例を交えて解説します。


staticとは?

staticクラスに属するという意味です。
通常の変数やメソッドはインスタンス(newで作ったオブジェクト)に属しますが、staticクラス自体に属するため、オブジェクトを作らずに使うことができます。


よくある疑問と回答


Q1. なぜmainメソッドにはstaticが付いているの?

A:Javaプログラムを実行するとき、まず「クラス」を読み込むから。

プログラム開始時点ではまだオブジェクトがありません。
そこで、オブジェクト不要で実行できるようにするためstaticが付いています。


Q2. static変数と普通の変数の違いは?

種類所属使うタイミング
インスタンス変数オブジェクトオブジェクトごとに独立した値を持ちたいとき
static変数クラス全オブジェクトで共有したいとき
例:カウンター(全インスタンスで共有)

countは全インスタンスで共有されるため、2回インスタンス化すると値が2になります。


Q3. staticメソッドっていつ使うの?

  • ユーティリティ処理

  • 共通的な値や処理

  • インスタンスの状態に依存しないメソッド

例:Mathクラス

Mathクラスはnewしません。
staticの代表例です。


Q4. staticを付けすぎるとどうなる?

オブジェクト指向らしさが失われます。

  • 何でもかんでもstatic → 関数型プログラムみたいになる

  • 状態(フィールド)を持つ設計が難しくなる

✅ ルール

  • 状態を持つもの → インスタンス

  • 共通処理 → static


まとめ

用語意味
staticクラスに属する(オブジェクト不要)
static変数全インスタンスで共通の変数
staticメソッドインスタンスに依存しない処理
mainメソッドがstaticな理由最初はオブジェクトがないため

まずは「オブジェクト不要で使える」だけ覚えてOK!
使いながら感覚をつかみましょう ✅

Java 8以上でリストをマージ・変換・フィルタリングするプロ向け実践術

✅ はじめに:Java 8以降の開発では「リスト操作力」が問われる

Java 8以降、Stream APIの登場によってListの操作が劇的に効率化されました。
しかし──

✅ addAllやfor文と混在してコードが読みづらくなる
✅ mapとflatMapを使い分けられない
✅ filterの順序ミスでパフォーマンス劣化
✅ null対策が甘く実行時例外が発生
✅ collectの最適な書き方がわからない

…といった悩みを抱える開発者は少なくありません。

本記事では、**「プロが実務で使うリスト処理の実践術」**を、マージ・変換・フィルタリングに焦点を当てて徹底解説します。


✅ Stream APIの基本構造

✅ Streamは元のリストを壊さない(非破壊的)
✅ 中間操作は評価されず蓄積 → 終端操作で初めて実行
✅ メソッドチェーンで可読性UP


✅ 1. リストをマージ(結合)する3つの実践パターン

❗ 従来の書き方(非推奨)

✅ ① Stream.concat()

✅ ② flatMapを使った複数リスト統合

✅ リストを動的に渡す場合にも有効


✅ 2. リストの変換(map・flatMap)実践術

✅ map(1対1変換)

✅ flatMap(1対多変換に最適)

✅ 「map + 非Stream返却」ならmap
✅ 「map + Stream返却」ならflatMap


✅ 3. フィルタリング(filter)応用パターン

✅ 基本

✅ 複数条件

✅ Optional併用(null安全)


✅ 4. プロが多用する応用操作

操作用途サンプル
distinct重複削除.distinct()
sorted並び替え.sorted(Comparator.comparing(User::getAge))
groupingByグループ化Collectors.groupingBy(User::getDepartment)
collectingAndThen集約後処理.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList))

✅ Before / Afterで理解:IDの重複を削って並べる

❌ 従来(冗長)

✅ Stream版(たった1行)


✅ 5. パフォーマンス注意点

NGOK理由
filter後にmapmap後にfilterマッピングが無駄になる
distinct前にmapmap後にdistinct重複を早く削る
flatMap多用必要時のみネストが深いと重い
無闇なparallel()データ量が少ないと逆効果

✅ 最後に:Stream APIは「読みやすく・壊さない」が正解

✅ 冗長なfor文はStreamで置き換え
✅ mapとflatMapは「1対1」「1対多」で使い分け
✅ filterは前処理に最適
✅ Optional併用でnull対策
✅ groupByやdistinctで実務効率化

「使える」から「読みやすい」「安全」「再現性のある」コードへ。

Mapの操作がここまで楽になる!Java 8のcomputeIfAbsent/merge徹底活用術

はじめに:Map操作、まだ「containsKey」で書いていませんか?

JavaでMapを使うとき、以下のようなコードを書いた経験はありませんか?

Java 8以前ではこれが一般的でした。しかしJava 8では、computeIfAbsentmergeを使うことで、こうした冗長なコードをたった1行で表現できます!

本記事では、これらのメソッドの使い方から実践例まで徹底的に解説します。


✅ computeIfAbsentとは?

🔍 役割

キーが存在しないときに初期値を生成しMapに登録する。

📌 シグネチャ

✅ 使用例:リストを保持するMapに要素を追加する場合

📉 Before(従来のコード)

📈 After(computeIfAbsentで1行に)

👉 このように、存在確認不要でスッキリ!


✅ mergeとは?

🔍 役割

指定したキーに対して、既に値がある場合は「結合処理」を行い、新規ならそのまま値を格納。

📌 シグネチャ

✅ 使用例:カウントアップ処理

📉 Before(キー存在チェックあり)

📈 After(mergeで1行)

👉 キーがなければ1を設定。あれば現在値と1を足す。美しい!


✅ computeIfAbsentとmergeの使い分け

ケース推奨メソッド
値を「初期化してから操作」したいcomputeIfAbsent
「集計・加算・結合」したいmerge
ListやSetを使うMapに要素を追加したいcomputeIfAbsent
数値や文字列をまとめたいmerge

✅ さらに活用例:文字列の出現回数カウント

📤 出力:

{apple=2, banana=2, orange=1}

✅ Listを使ったグルーピングも簡単に!

📤 出力:

{A=[Apple, Avocado], B=[Banana]}

✅ まとめ:Map操作はJava 8で劇的にスマートになる!

キーワード内容
computeIfAbsent値がない場合のみ初期化
merge既存値と競合処理(加算・結合など)
メリットif文不要・コードが短く読みやすくなる

if文から卒業!Java 8のPredicateで条件分岐をスマートに書く方法

Javaで複雑な条件分岐が増えてくると、if文がネストして読みにくくなる…という悩みを抱えたことはありませんか?
Java 8で追加された**Predicateインターフェース**を使えば、条件式をオブジェクトとして扱えるため、よりスマートで再利用可能な形にできます。

本記事では、Predicateの基本から複数条件の組み合わせ、実用的な活用例まで分かりやすく解説します。


✅ Predicateとは?

Predicate<T> はJava 8で導入された関数型インターフェースで、**「引数を1つ受け取り、booleanを返す関数」**を表します。

test()メソッドに条件式を実装することで、条件判定を行うことができます。


✅ 基本的な使い方

✔ Lambda式で判定条件を定義

ここで、age -> age >= 20 という条件式がPredicateとして表現されています。


✅ 条件を組み合わせる(and/or/negate)

Predicateは以下のような便利なメソッドを持っています。

メソッド説明使用例
and()両方trueでtrueAND条件
or()どちらかtrueでtrueOR条件
negate()条件を反転NOT条件

✔ 使用例


✅ 実用例①:従来のif文から置き換えてスマートに

❌ 従来のif文

✅ Predicateを使った場合

→ 条件式をPredicateとして切り出すことで、再利用しやすくなります。


✅ 実用例②:Listのフィルタリングに活用

stream().filter() と組み合わせるとさらに強力です。

→ 条件式が外部に切り出されることで、読みやすく拡張しやすいコードになります。


🎯 Predicateを使うメリット

項目従来のif文Predicate
可読性ネストしやすい条件名で意図が明確
再利用性条件をコピペ使い回し可能
拡張性if追加が必要and/orで柔軟に拡張

⚠ 濫用しすぎには注意!

Predicateは便利ですが、小規模な処理に無理に使うと逆に複雑化することがあります。
「条件が複数箇所で使い回せる場合」や「複雑なAND/OR条件を定義したい場合」に効果を発揮します。


✅ まとめ

項目内容
Predicateとはbooleanを返す関数型インターフェース
基本test() で条件判定
条件組み合わせand/or/negateでスマートに
実用例if文の代替・Streamのfilterで活躍
メリット可読性・再利用性UP

👉 if文が増えて可読性が下がってきたと感じたら、まずは小さな条件式からPredicate化してみましょう!

Java:Stream APIのparallelStream()で並列処理を簡単に実現する方法

🔷 はじめに

JavaのStream APIは、コレクション操作を簡潔に記述できる便利な仕組みですが、
parallelStream()を使うことで マルチスレッド処理(並列処理) を手軽に実現できます。

この記事では、parallelStream()の基本的な使い方から、注意点・パフォーマンスの最適化方法までをわかりやすく解説します。


🔷 StreamとparallelStreamの違い

種類説明特徴
stream()通常の逐次処理1スレッドで順次実行される
parallelStream()並列処理ForkJoinPoolを使って複数スレッドで分割実行される

上記のparallelStream()では、スレッドごとに要素を分割して処理するため、
出力順が異なる(順不同になる)点に注意が必要です。


🔷 並列処理の仕組み(ForkJoinPool)

parallelStream()は内部的に ForkJoinPool(フォーク・ジョイン・プール)を使用します。
デフォルトでは、Runtime.getRuntime().availableProcessors() の値(CPUコア数)に応じてスレッド数が自動決定されます。

例えば、4コアCPUの場合は最大4スレッドで同時実行されます。


🔷 実行例:リストの重い処理を並列化する

以下の例では、重い計算を伴う処理を並列実行して速度を比較します。

結果例:

逐次処理時間:5000ms
並列処理時間:1500ms

CPUコア数にもよりますが、並列処理では約3倍の高速化が期待できます。


🔷 並列処理時の注意点

注意点内容
スレッド安全性共有リソースを操作すると競合が発生する可能性あり
出力順forEach()は順序が保証されない(順序を保つにはforEachOrdered()を使用)
外部API呼び出し同時実行でAPI制限に抵触する可能性があるため注意
numbers.parallelStream()
.forEachOrdered(System.out::println); // 並列でも順序維持

🔷 並列処理の最適化テクニック

  1. 処理が軽い場合は使わない

    • 並列化のオーバーヘッドが大きく、逆に遅くなる場合があります。

  2. データ量が多い処理に限定する

    • 数千件以上の要素を扱う場合に効果的。

  3. カスタムスレッド数を指定

    • これで並列スレッド数を8に固定できます。


🔷 parallelStream()を使うべきケース

CPUバウンド処理(計算中心)
データが多い場合
スレッド安全な処理のみを行う場合

I/Oバウンド処理(ファイル操作・DBアクセス)は非推奨です。
並列化よりも非同期I/O(CompletableFutureなど)を使うほうが効率的です。


🔷 まとめ

項目内容
メリット複雑なスレッド処理を書かずに並列化できる
デメリット順序保証がない・スレッド安全性に注意
向いている処理CPU負荷の高いループ・数値計算・マッピング処理
非推奨の処理I/O、同期が必要な共有データ操作

parallelStream()は数行で並列化を実現できる強力なツールですが、
適切な場面で使うことが重要です。
CPUをフル活用して処理時間を短縮したい場面で、ぜひ活用してみてください。

Java Stream API入門:リスト操作を効率化する実用サンプル集

■ 導入:Stream APIでコードを劇的に簡潔化

Java 8以降で導入された Stream API は、リストや配列の操作を「宣言的」「関数型スタイル」で記述できる強力な仕組みです。
従来の for ループを使った処理に比べて、コード量を大幅に削減し、バグを防止 できます。

本記事では、List 操作を中心に、Stream APIの実践サンプルを多数紹介します。


■ 基本構文:Streamの流れを理解する

Streamの基本構成は以下の3ステップです。

イメージ:

データの流れ → 加工 → 出力(別のリストなどに変換)

■ サンプル①:条件でフィルタリングする

例えば「偶数だけを抽出する」処理は、以下のように書けます。

処理内容コード例説明
偶数のみ抽出filter(n -> n % 2 == 0)条件に一致する要素だけを残す

■ サンプル②:要素を変換する(map)

全ての要素を2倍にする変換も簡単です。

処理内容コード例出力例
2倍変換map(n -> n * 2)[2, 4, 6, 8]

■ サンプル③:ソート・並び替え

文字列リストをアルファベット順にソートする例です。

降順にする場合は:

処理内容メソッド説明
昇順ソートsorted()自然順序(A→Z, 1→9)
降順ソートsorted(Comparator.reverseOrder())逆順に並び替え

■ サンプル④:重複を除去する(distinct)

処理内容メソッド効果
重複削除distinct()同一要素を1つにまとめる

■ サンプル⑤:合計・平均・最大値を求める

数値リストの集計処理も簡単です。

処理メソッド結果型
合計sum()int
平均average()OptionalDouble
最大max()OptionalInt

■ サンプル⑥:複数条件の処理(filter + map)

処理順序内容
Aで始まる要素のみ抽出
すべて大文字に変換
新しいリストに収集

■ サンプル⑦:グルーピング(groupingBy)

Stream APIでは、SQLのように「グループ化」も可能です。

処理内容メソッド結果
長さごとにグループ化groupingBy(String::length){3=[Tom, Ken], 4=[John]}

■ サンプル⑧:並列処理で高速化(parallelStream)

大量データを高速処理したい場合は parallelStream() を使います。

ただし、順序が保証されない ため、結果の順序が重要な場合は通常の stream() を使用しましょう。


■ Stream APIを使うメリットまとめ

メリット内容
コードの簡潔化for文やif文のネストを削減
可読性向上処理の流れが直感的に理解できる
パフォーマンス並列処理で大量データにも対応
安全性NullPointerExceptionを防ぎやすい

■ まとめ:Stream APIを使いこなして効率化

Stream APIは一度慣れてしまえば、リスト処理を格段に楽にしてくれます。
特にJava 11以降では、ラムダ式やメソッド参照との相性も良く、業務アプリのコード品質を底上げできます。

🧩 Oracle「ORA-01000: 最大オープン・カーソル数を超えました」対処手順

🔍 エラー概要

項目内容
エラーコードORA-01000
メッセージ最大オープン・カーソル数を超えました
発生原因開いたカーソルをクローズせずに処理を繰り返した結果、open_cursors の上限に達した
対応優先度高(アプリケーション修正・設定見直しが必要)

🧠 原因と仕組み

Oracle では、SQL 実行時に「カーソル」という内部ハンドルを使用して SQL 文を管理します。
アプリケーションが PreparedStatementResultSet を閉じずに再利用し続けると、未解放のカーソルが蓄積し、open_cursors パラメータで設定された上限値を超えた時点で ORA-01000 が発生します。


🧩 よくある原因パターン

原因詳細
JDBCのクローズ漏れResultSet や Statement を close() していない
ループ内で毎回 SQL を preparePreparedStatement を都度生成して再利用していない
コネクションプールの設定ミスコネクションが正しく解放されず、カーソルが残存
長時間実行バッチ同一セッションで大量SQLを連続実行してカーソルが累積
外部ライブラリのバグORM(MyBatis、Hibernate等)でのカーソル管理不具合

🧭 対処法(順序付き)

手順対処内容
アプリケーションコードを点検(ResultSet, Statement, Connection を確実に close)
try-with-resources 構文を使用して自動クローズ化(Java7以降推奨)
open_cursors パラメータ値を確認(show parameter open_cursors;)
必要に応じて上限を引き上げ(例:ALTER SYSTEM SET open_cursors = 1000 SCOPE=BOTH;)
v$open_cursor ビューで調査(どのSQLが残っているか確認)

🔧 調査SQL例 


💡 Javaでの修正例(try-with-resources構文)

✅ これにより、ResultSetPreparedStatementConnection が自動的にクローズされます。


⚙️ open_cursors の推奨設定値

システム規模推奨値備考
開発・検証環境300〜500検証負荷に応じて柔軟に設定
小〜中規模業務システム500〜1000通常アプリでは十分
大規模バッチ・Webサービス1000〜2000コネクションプール利用時に余裕をもたせる

🚨 注意点

  • open_cursors の値を単純に上げるだけでは根本解決になりません。
    アプリケーションでのクローズ処理修正が最優先

  • 定期的に v$open_cursor を監視することで、リークを早期発見できます。


✅ まとめ

観点内容
発生原因カーソルの未クローズや過剰生成
一時対応open_cursors の増加
根本対応コード修正(try-with-resources等)
チェック方法v$open_cursor / v$sesstat ビュー
再発防止コーディング規約・静的解析の導入