F
freakxnet
Schönen guten Tag,
irgendwie habe ich die Vermutung das im Java JDBC ein fieser Bug drinn hängt. Ich bin jetzt schon seit tagen am Rätseln warum ich so ein enormes Speicherleck habe.
Das leck tritt dann auf wenn ich auf der Datenbank relativ große Datenmengen auslese. Das Result wird dann aber nicht wieder frei gegeben. Aus diesem Grund habe ich mal eine kleine Testanwendung geschrieben was das Problem verdeutlicht.
Testsysteme:
1)
Windows XP Professional SP3
Wamp2
MYSQL 5.1.30
SUN Java 1.6
2)
Windows XP Professional SP3
PostgreSQL HTTPD Server
PostgreSQL 8.1
SUN Java 1.6
3)
Linux FEDORA Core 11
Apache2
MYSQL
OpenJDK 1.6
Nun ist es so das ich in meiner Datenbank eine Testtabelle (Defintion unten) angelegt habe welche ich mit Daten gefüllt habe (1 Mio. Datensätze). Dort führe ich dann das SELECT darauf aus. Leider ist es dann so das ja laut Java-Doku bei einem "CLOSE" alle Daten freigegeben werden. Jetzt "CLOSE" ich alles und aber leider wird der Speicher dann nicht mehr freigegeben. Kann es sein das ich etwas vergessen habe oder irgendwie etwas komplett verreiße? Nach meiner Aufassung müsste er doch wenn ich alles "CLOSE" die Speicher wieder freigeben. Dies ist aber eben nicht der Fall.
Falls da jemand eine Lösung oder eine Idee dazu hat wäre ich über einen Ratschlag sehr verbunden.
MFG freakxnet
====DAS JAVA PROG======
irgendwie habe ich die Vermutung das im Java JDBC ein fieser Bug drinn hängt. Ich bin jetzt schon seit tagen am Rätseln warum ich so ein enormes Speicherleck habe.
Das leck tritt dann auf wenn ich auf der Datenbank relativ große Datenmengen auslese. Das Result wird dann aber nicht wieder frei gegeben. Aus diesem Grund habe ich mal eine kleine Testanwendung geschrieben was das Problem verdeutlicht.
Testsysteme:
1)
Windows XP Professional SP3
Wamp2
MYSQL 5.1.30
SUN Java 1.6
2)
Windows XP Professional SP3
PostgreSQL HTTPD Server
PostgreSQL 8.1
SUN Java 1.6
3)
Linux FEDORA Core 11
Apache2
MYSQL
OpenJDK 1.6
Nun ist es so das ich in meiner Datenbank eine Testtabelle (Defintion unten) angelegt habe welche ich mit Daten gefüllt habe (1 Mio. Datensätze). Dort führe ich dann das SELECT darauf aus. Leider ist es dann so das ja laut Java-Doku bei einem "CLOSE" alle Daten freigegeben werden. Jetzt "CLOSE" ich alles und aber leider wird der Speicher dann nicht mehr freigegeben. Kann es sein das ich etwas vergessen habe oder irgendwie etwas komplett verreiße? Nach meiner Aufassung müsste er doch wenn ich alles "CLOSE" die Speicher wieder freigeben. Dies ist aber eben nicht der Fall.
Falls da jemand eine Lösung oder eine Idee dazu hat wäre ich über einen Ratschlag sehr verbunden.
MFG freakxnet
====DAS JAVA PROG======
Code:
package src;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
*
* @author freakxnet
*
* TABLE DATA - MYISAM TABLE
*
* -- phpMyAdmin SQL Dump
-- version 3.1.1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Erstellungszeit: 30. September 2009 um 21:20
-- Server Version: 5.1.30
-- PHP-Version: 5.2.9-2
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- Datenbank: `test`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `test`
--
DROP TABLE IF EXISTS `test`;
CREATE TABLE IF NOT EXISTS `test` (
`id` int(11) NOT NULL DEFAULT '0',
`test1` varchar(255) NOT NULL,
`test2` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `test1` (`test1`,`test2`)
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
--
-- Daten für Tabelle `test`
--
*
*/
public class DBTest {
private Connection connection;
public DBTest(){
this.connectToDatabase();
//this.fillTable();
this.selectTable();
}
/**
* Connect to database
*/
private void connectToDatabase(){
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
this.connection=DriverManager.getConnection("jdbc:mysql://localhost/sitedata","root", "root");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* Fill the table with random data
*/
private void fillTable(){
//fill in one million entries
int numEntrys=1000000;
Statement statement=null;
try {
//create the statement
statement=this.connection.createStatement();
//start transaction
statement.execute("begin");
for(int cnt=0; cnt<numEntrys; cnt++){
statement.execute("INSERT INTO test (test1, test2) VALUES('testValue1["+cnt+"]', 'testValue2["+cnt+"]');");
}
//commit data to table
statement.execute("commit");
//clears out all warnings
statement.clearWarnings();
//close the statement
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
try {
statement.clearWarnings();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//close the current connection
try {
this.connection.clearWarnings();
this.connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* Selects a number of rows from database
*/
private void selectTable(){
System.out.println("Start: "+(Runtime.getRuntime().freeMemory()));
Statement statement;
try {
statement = this.connection.createStatement();
ResultSet result=statement.executeQuery("SELECT * FROM test LIMIT 500000");
System.out.println("After query: "+(Runtime.getRuntime().freeMemory()));
result.clearWarnings();
result.close();
statement.clearWarnings();
statement.close();
this.connection.clearWarnings();
this.connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("End: "+(Runtime.getRuntime().freeMemory()));
boolean running=true;
while(running){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]){
new DBTest();
}
}