Java-Tomcat GC不会释放。。总是导致崩溃,找不到任何内存泄漏
我的tomcat应用程序没有什么问题。 我使用的是一个有1024M内存的linux服务器。 我在tomcat上部署了我的应用程序,一切都很好。 最近我注意到“终身世代”堆内存在应该释放的时候没有释放出来。。。 它达到99%,然后使tomcat崩溃。。 我用VisualVM检查我的应用程序,得到了相同的结果。 它填满了记忆,而“老一代”永远无法释放 这是指应用程序在没有请求的情况下运行几分钟: IMG: 当我开始发送循环中有200个线程的请求时 发生了这样的事情: IMG: 然后我检查垫子上的数据,这是我的结果: IMG: IMG: IMG: 这是我的ConnectionPool类: 请帮助我理解什么是错误的,并解释我 1.为什么总承包商不释放,或者为什么他不能完成他的工作 2.我的ConnectionPool课程有问题吗Java-Tomcat GC不会释放。。总是导致崩溃,找不到任何内存泄漏,java,tomcat,garbage-collection,jvm,out-of-memory,Java,Tomcat,Garbage Collection,Jvm,Out Of Memory,我的tomcat应用程序没有什么问题。 我使用的是一个有1024M内存的linux服务器。 我在tomcat上部署了我的应用程序,一切都很好。 最近我注意到“终身世代”堆内存在应该释放的时候没有释放出来。。。 它达到99%,然后使tomcat崩溃。。 我用VisualVM检查我的应用程序,得到了相同的结果。 它填满了记忆,而“老一代”永远无法释放 这是指应用程序在没有请求的情况下运行几分钟: IMG: 当我开始发送循环中有200个线程的请求时 发生了这样的事情: IMG: 然后我检查垫子上的数据
3.为什么tomcat在我的日志中没有提到OutOfMemoryException只是崩溃?查看连接详细信息,显然您有10个连接,每个连接都保留了cca 66 MB,如果堆加起来需要660 MB的RAM 我不知道您选择了什么数据,但是当返回连接时,您可能希望关闭所有结果集和语句,为什么要创建自己的池?dbcp、c3p0或公用池不够好?为了学习?似乎这还不够。我真的不知道池实现如何正确地释放所有资源
在多个线程之间共享开放连接似乎不是那么简单,因此我建议使用工作池解决方案dbcp只有1Gb的服务器非常小,操作系统本身和jvm以外的其他服务也需要使用内存,-Xms和-Xmx的jvm设置是什么?我尝试了很少的内存大小,现在是-Xms256M-xmx512m扔掉您的连接池,使用Apache:DBCP中的连接池。没有理由重新发明这个轮子。所以你认为如果我买一台更大的服务器,问题会得到解决吗?不。为什么MAT告诉我内存泄漏?因为你可能确实有内存泄漏。但解决办法是消除最可能的原因。。。这是您的连接池实现。具体来说,集合allConnections在代码中没有任何用处,只是在closeAllConnections中它被遍历但从未清除,这是此代码中至少有一个漏洞的位置。你可以通过从一开始就不犯这样的基本错误来避免。您不需要CloseAllConctions方法;您不需要allConnections集合;而且,当存在仅实现现有连接接口的工作实现时,您当然不需要具有自己API的连接池实现。。非常感谢。
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");
}
}