我的tomcat应用程序几乎没有问题。我使用的是具有1024m内存的Linux服务器。我将应用程序部署在Tomcat上,一切正常。最近,我注意到"终身终身"的堆内存在应该...它达到99%,然后撞车。我使用VisualVM检查了我的应用程序,并且结果相同。它充满了记忆,"旧的gen"永远不会释放。
这是应用程序运行几分钟而没有请求的时候:
img:一切看起来正常
当我开始在循环中发送200个线程的请求时这发生了什么:
img:所有记忆均已完整
所以我检查垫子上的数据,这是我的结果:
img:看起来像记忆泄漏
img:SQL JDBC的问题?
img:无法理解什么是错误的
这是我的ConnectionPool class
:
public class ConnectionPool {
private static ConnectionPool singleton = null;
private ArrayList<Connection> freeConnections;
private ArrayList<Connection> allConnections;
private int MAX_CONNECTIONS = 1;
private final String shema = "Topic";
private final String url = "jdbc:mysql://localhost:3306/"+shema+"? autoReconnect=true&useSSL=false";
private final String username = "root";
private final String password = "password";
public static ConnectionPool getInstance(){
if (singleton == null)
{
synchronized (ConnectionPool.class) {
if (singleton == null){
System.out.println("ConnectionPool get instance");
try {
singleton = new ConnectionPool();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //this will invoke the constructor
}
}
}
return singleton;
}
private ConnectionPool() throws Exception {
freeConnections = new ArrayList<Connection>();
allConnections = new ArrayList<Connection>();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < MAX_CONNECTIONS; i++) {
try {
addNewConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void addNewConnection() throws SQLException {
try {
Connection conn = DriverManager.getConnection(url, username, password);
freeConnections.add(conn);
allConnections.add(conn);
} catch (SQLException e) {
throw e;
}
}
public Connection getConnection()
{
while (true) {
synchronized (freeConnections) {
if (freeConnections.size() != 0) { // free connection is available
Connection conn = freeConnections.get(0);
freeConnections.remove(0);
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
try {
freeConnections.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void returnConnection(Connection conn)
{
if (null == conn) { // ignore invalid value
return;
}
if (!allConnections.contains(conn)) {
return;
}
synchronized (freeConnections) {
if (freeConnections.contains(conn)) {
return;
}
freeConnections.add(conn);
freeConnections.notifyAll();
return;
}
}
public void closeAllconnections()
{
for (Connection conn : allConnections) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
System.out.println("ConnectionPool all connection closed");
deregisterDriver();
}
public void deregisterDriver() {
try {
java.sql.Driver driver = DriverManager.getDriver(url);
DriverManager.deregisterDriver(driver);
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("ConnectionPool deregister driver");
}
}
请帮助我了解错误并解释我。
1.为什么GC无法释放或为什么他不能做工作?
2.我的ConnectionPool Class
有问题?
3.为什么tomcat在我的日志中没有说任何有关OutOfMemoryException
的信息(只是崩溃(?
请参阅连接详细信息,显然您有10个连接,并且每个连接保留了CCA 66 MB,如果堆口最高可达660 MB所需的RAM。
我不知道您选择哪些数据,但是当返回连接时,您可能需要关闭所有结果集和语句(为什么要创建自己的池?dbcp,c3p0或commons-pool aiin ain不够好?学习?(,似乎还不够。我真的不知道泳池实施如何正确发布所有资源。
,似乎并不那么直接在多个线程之间共享开放连接Java MySQL JDBC内存泄漏,因此我建议使用工作池解决方案(DBCP(