ヒープメモリ使用量増加問題とメモリリークの原因について

このQ&Aのポイント
  • Connectionオブジェクトをインスタンス変数として持つDBManagerクラスのオブジェクトをクラスAのコンストラクタの引数として渡し、100万回のループ処理を行うとヒープ領域の使用量が増加する問題が発生しています。
  • EclipseのMemoryAnalyzerによる解析結果では、Heapの90%以上がConnectionオブジェクトによって占有されていることが分かりました。
  • クラスAのオブジェクトがループ処理の中にあることによってConnectionオブジェクトが増加する可能性があり、インスタンス変数としてクラス内に存在することがメモリリークの原因となる可能性があります。
回答を見る
  • ベストアンサー

ヒープメモリについて

下記のソースにあるようにConnectionオブジェクトをインスタンス変数として持つ DBManagerクラスのオブジェクトをクラスAのコンストラクタの引数として渡す。 さらにそのクラスAのインスタンスメソッドであるinsert()をforループで100万回ほど 回すというような作りのソースがあります。 これを実行した時、JConsoleでヒープ領域をモニタリングすると徐々に使用量が増加していきます。 さらに、EclipseのMemoryAnalyzerなどで解析してみるとHeapの90%以上をConnectionのオブジェクト が占有しているという結果が出ました。 クラスAのオブジェクトaがループ処理の中にあることによってConnectionオブジェクトが増加すること はあり得るのでしょうか。インスタンス変数としてクラスの中に存在するとそれは メモリリークの原因となるのでしょうか。 pulic class DBManager { Connection conn; pubulic DBManager() { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(jdbc:mysql://localhost/test,user,pass); } public close() { conn.close(); } } public class A() { DBManager db; public A(DBManager db) { this.db = db; } } public class test { public static void main(String args) { DBManager db = new DBManager(); A a = new A(db); for(int i=0;i<1000000;i++) { a.insert(); } db.close(); } }

  • Java
  • 回答数1
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

A#insert()で何やってるかわからないので、なんとも言えません。 それに、gc走って消えるなら何の問題も無いし。 gc走っても消えないの?

関連するQ&A

  • ADODB.Connectionはインターフェイス

    いつもお世話になっております。 C#で特定のDBに接続するクラスを作ろうとADODB.Connection(ADO.Conn)を継承しようとしたところADO.Connはインターフェイスであるため、各メンバの実装をしなくてはなりません。ADO.Connはオブジェクトととしてインスタンスを生成できていたため、なぜインターフェイスがインスタンスを生成してオブジェクトとして使えるのかがわかりません(Excel.Applicationなども同様です)。 これはどのような仕組みになっているのでしょうか?

  • サーブレットとMysqlについて

    画面のtextboxからDB(Mysql)にinsertするときの質問です。 皆さんのおかげでinsertすることができました。 しかし、textboxが一個で値も一つなのに、 insertするとDBには2行同じ値がinsertされます。 下記のソースのどこがいけないのでしょうか? ご教示をお願いします。 「ソース」 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name10 = request.getParameterValues("sonota"); for (int i = 0; i < name10.length; i++) { System.out.println(i + " " + name10[i]); name10[i] = new String(name10[i].getBytes("8859_1"), "UTF-8"); } Connection conn = null; CallableStatement cs = null; PreparedStatement stmt = null; ResultSet rs = null; String url = "jdbc:mysql://localhost/Sample_db"; String dbUser = "root"; String dbPass = "taratara"; try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection(url, dbUser, dbPass); String sql= "insert into Sample_table (name) values (?)"; stmt = conn.prepareStatement(sql); for (String n : name10) { stmt.setString(1, n); stmt.executeUpdate(); } int cnt = stmt.executeUpdate(); stmt.close(); RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp"); dispatcher.forward(request, response); }catch(Exception e){ } } }

  • サーブレット mysqlについて

    JSP サーブレット mysqlについて質問です。 私が今実現させたいことを簡単に説明します。画面側にはtextboxがあり、このtextboxは追加ボタンによって、 どんどん追加されていきます。 サーブレット側はこのtextboxの全ての値をDBに書き込みたいです。 例えば、textboxが二つなら、一つ目のINSERTでDBのagi列にagis1とname列にtextbox一個目の値を書き込み、二つ目のINSERTでDBのagi列にagis2とname列にtextboxニ個目の値を書き込む。 ソースを書いてみたのですが、いろいろと違いがあると思いますので、ご教示をお願いします。 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name = request.getParameterValues("sonota"); Connection conn = null; Statement state = null; int count = 0; try { //コネクション接続 Class.forName("org.git.mm.mysql.Driver"); conn = DriverManager.getConnection( "jdbc:mysql://localhost/Sampl_db", "root", "taratara"); state = conn.createStatement(); String agis = getInitParameter("agis[i]"); for (int i = 0; i < agis.length(); i++) { //クエリ実行 state.executeUpdate( "INSERT INTO Sampl_teble(agi, name) VALUES(" + agis + ", " + name + ")"); } //影響レコード数出力 System.out.println(count); } finally { //ステートメントを閉じる if(state != null) { try { state.close(); } catch (Exception e) { //このエラー処理は「state.close」でエラーが発生した場合でも //下記処理が実行される為に記述しています。 } } //コネクションを閉じる if(conn != null) { conn.close(); } } }

    • ベストアンサー
    • Java
  • サーブレットとMysqlについて

    JSP サーブレット Mysqlについて質問です。 私が今実現させたいことを簡単に説明します。 画面側にはtextboxがあり、このtextboxは追加ボタンによって、 どんどん追加されていきます。 サーブレット側はこのtextboxの全ての値をDBに書き込みたいです。 例えば、textboxが二つなら、一つ目のINSERTでDBのname列にtextbox一個目の値を書き込み、二つ目のINSERTでDBのname列にtextboxニ個目の値を書き込む。 ソースを書いてみたのですが、いろいろと違いがあると思いますので、ご教示をお願いします。 現在は下記ソースを実行してもDBは更新されません・・ もしかしたら、DBの設定がおかしいのでしょうか・・ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name10 = request.getParameterValues("sonota"); for (int i = 0; i < name10.length; i++) { System.out.println(i + " " + name10[i]); name10[i] = new String(name10[i].getBytes("8859_1"), "UTF-8"); } Connection conn = null; CallableStatement cs = null; PreparedStatement stmt = null; ResultSet rs = null; String url = "jdbc:mysql://localhost/Sample_db"; String dbUser = "root"; String dbPass = "taratara"; try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection(url, dbUser, dbPass); String sql= "insert into Sample_db.Sample_table (name) values (name10[i]);"; stmt = conn.prepareStatement(sql); for (String n : name10) { stmt.setString(1, n); stmt.executeUpdate(); } int cnt = stmt.executeUpdate(); stmt.close(); }catch(Exception e){ //exception RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp"); dispatcher.forward(request, response); } } }

    • ベストアンサー
    • Java
  • Androidから外部DBサーバーへ接続(MySQL)

    現在、Androidのアプリで、ボタンを押下したらWindows上のMySQLサーバーに接続し、データを取得しようとしています。 しかし、どうしてもDBサーバーに接続できません。 Exceptionに飛んでしまいます。 どなたかご教授ください><; 【環境】 ・Windows Vista Home Premium ・eclipse 3.5上でAndroidをエミュレーション ・MySQL 5.1を使用 ・JDBCドライバは5.1を使用  プロジェクトの構成パスにJDBCを追加 【ソースコード(接続部分のみ)】 import java.sql.*; (中略) public void onClick(Veiw v) {   try {     Class.forName("com.mysql.jdbc.Driver);     Connection conn = DriverManager.getConnection("jdbc:mysql://localhost; DatabaseName=DBName;", "user", "pass");     Statement stmt = conn.createStatement();     (中略)   } catch (Exception ex) {     // エラー   } }

  • PHP/mySQLでインサートができません。

    PHPとmySQLを勉強中の初心者ですが、よろしくお願いします。 PHPで簡単なインサート文を作ってそれをmySQLに保存しようとしているのですが、以下のエラーが出てしまいます。 Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource プログラムは以下の通りです。HOSTNAME,USERNAME,DBPWDは別のところで定義していますが、mysql_connect, mysql_select_dbではエラーにならないので、データベースの選択まではうまく行っていると思うのですが。 $conn = mysql_connect(HOSTNAME, USERNAME, DBPWD); if(!$conn){ die("Logon Failure to mysql Server."); } $db = mysql_select_db(DBNAME, $conn); if(!$db){ die("Cannot access to the DB"); } foreach($csv_ary as $a => $b) { $query = "INSERT INTO TEST field_a VALUES $a"; if (!mysql_query($query, $db)){ echo "更新失敗: SQL=$query<br>"; } } mysql_close($conn); field_aはvarchar(10)でPrimary_key, NOT NULLの設定です。 Foreachで展開した配列の値はちゃんと長さ10の文字列が入っています。 PHP 4.3.11は mySQL 4.0.27です。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • JDBCドライバーのロードに関して

    参考書やwebページのソースコードにJDBCドライバーのロードのときに、Class.forName("...")と書いているものと、Class.forName("...").newInstance()と書いているものがあります。[...部分は省略]この二つのコードは、どこが違うのでしょうか。また、Sunmicroのホームページで、forNameメソッドは、"指定された文字列名を持つクラスまたはインタフェースに関連付けられた、Class オブジェクトを返します。"と、newInstanceメソッドは、"この Class オブジェクトが表すクラスの新しいインスタンスを生成します。"と書かれていますが、どうしてこれで、JDBCドライバーがロードされるのですか?また、初歩的な質問ですが、JDBCドライバーがロードされるというのは、どうゆうことですか?教えてください。

    • ベストアンサー
    • Java
  • ServletでJDBCを使う時

    servletでJDBCを使ってデータベースに接続しようと思っていますが、 servletのdoGetの中で、 Class.forName("com.mysql.jdbc.Driver"); と書くとClassNotFoundExceptionエラーになります。 public static Connection getConnection() などのクラスを作って、その中で Class.forName("com.mysql.jdbc.Driver"); と書くとエラーにはならないのですが、doGetの中では宣言できないのでしょうか?自分が何か勘違いしていたら申し訳ございません。 ご助言お願いいたします。

    • ベストアンサー
    • Java
  • 「Exception in thread "main" java.lang.NoClassDefFoundError: CUSTOMER」エラー

    Oracle9i R2にJDBCで接続してCUSTOMER表のレコード件数を調べる単純なJavaプログラムをつくろうとしています。 以下のソースをOracle端末上で実行すると「Exception in thread "main" java.lang.NoClassDefFoundError: CUSTOMER」というエラーメッセージが表示されます。 環境設定としてCLASSPATHにclasses12.zipのパスを通しました。 ------------------------------------------------- // JDBC APIのインポート import java.sql.*;class CUSTOMER { public static void main (String args[]) throws SQLException, ClassNotFoundException { // JDBC Driverの登録 Class.forName("oracle.jdbc.driver.OracleDriver"); // Oracle9iに接続 Connection conn = DriverManager.getConnection ("jdbc:oracle:thin@192.168.0.10:1521:testdb", "test", "test"); // ステートメントを作成 Statement stmt = conn.createStatement(); // 問い合わせの実行 ResultSet rset = stmt.executeQuery("SELECT COUNT(*) FROM CUSTOMER"); // 問い合わせ結果の表示 while ( rset.next() ) { // 列番号による指定 System.out.println(rset.getInt(1) + "\t" + rset.getString(2)); } // 結果セットをクローズ rset.close(); // ステートメントをクローズ stmt.close(); // 接続をクローズ conn.close(); } } ------------------------------------------------- 何かおわかりの方いらっしゃいましたら教えて下さい。宜しくお願いします。

    • ベストアンサー
    • Java
  • MySQL4.1における文字化けについて

    WindowsXPにてMySQL4.1.12aをインストールしました。 JDBCにて、 Class.forName("com.mysql.jdbc.Driver").newInstance(); String connStr = "jdbc:mysql:///databasename?user=root&password=pass" + "&useUnicode=true&characterEncoding=Shift_JIS"; とし、insertでCSVファイルから特定の項目を追加していくということをしました。 clientにてselectしてみたら、2バイト文字がすべて 「?」に変わっていました。 my.iniにて [mysqld] default-character-set = sjis [client] default-character-set = sjis [mysql] default-character-set = sjis を追加していますが、 statusで見ると mysql> status -------------- mysql Ver 14.7 Distrib 4.1.12a, for Win32 (ia32) Connection id: 1 Current database: shop Current user: root@localhost SSL: Not in use Using delimiter: ; Server version: 4.1.12a-nt Protocol version: 10 Connection: localhost via TCP/IP Server characterset: sjis Db characterset: utf8 Client characterset: latin1 Conn. characterset: latin1 TCP port: 3306 Uptime: 30 sec となっています。 utf8、latin1というのが文字化けの原因でしょうか。 対策方法をご教授お願いいたします。

    • ベストアンサー
    • MySQL