During the summer vacation, I made a project using SSH + mysql5.0 + atat5.5.
After deployment to the server (Tomcat is 6.0.32), the test runs normally. The next day, I found that I could not log on. I checked the system and found no problems. I restarted Tomcat and recovered to normal again.
Very strange, so I checked Tomcat logs and found the following problems:
2011-9-1 0:15:11 org. Apache. Catalina. startup. Catalina start
Information: server startup in 35866 MS
2011-9-1 2:05:43 org. Apache. Coyote. http11.http11protocol pause
Information: pausing coyote HTTP/1.1 on http-8080
2011-9-1 2:05:44 org. Apache. Catalina. Core. standardservice stop
Information: stopping service Catalina
2011-9-1 2:05:44 org. Apache. Catalina. loader. webappclassloader clearreferencesjdbc
Severe: the Web application [] registered the JDBC driver [COM. mySQL. JDBC. driver] but failed to unregister it when the web application was stopped. to prevent a memory leak, the JDBC driver has been forcibly unregistered.
2011-9-1 2:05:45 org. Apache. Coyote. http11.http11protocol destroy
Information: Stopping coyote HTTP/1.1 on http-8080
The error message is that the application registered the JDBC driver, but the driver cannot be deregistered when the program stops. To prevent memory overflow, Tomcat is forcibly deregistered.
I found many discussions on this issue on the internet, saying it was a DBCP bug.
The details are as follows:
Https://issues.apache.org/jira/browse/DBCP-332
Description
Basicdatasource's method close () Doesn't deregister JDBC driver. this causes permgen memory leaks in Web server environments, during context reloads. for example, using Tomcat 6.0.26 with spring, and basicdatasource declared in spring context, there is a message
Printed at web application reload:
Severe: A web application registered the jbdc driver [COM. mySQL. JDBC. driver] but failed to unregister it when the web application was stopped. to prevent a memory leak, the JDBC driver has been forcibly unregistered.
I was able to fix it by overriding close method this way:
public class XBasicDataSource extends BasicDataSource { @Override public synchronized void close() throws SQLException { DriverManager.deregisterDriver(DriverManager.getDriver(url)); super.close(); }}
But I think it shoshould be probably the default behavior of basicdatasource. Or perhaps there shoshould be some flag/setting on basicdatasource, named "deregisterdriveratclose" or so.
My system does not use spring to configure the data source.
Tomcat introduced the Memory Leak Detection Function after version 6.0.24. When the system finds that garbage cannot be recycled, It outputs log information.
After reading a lot of discussions about this issue, it seems that no good solution has been found. Some say that if the Tomcat memory listener is shut down, this exception will not be reported, but if it is not reported, it is not equal to no problem, and it still cannot be solved. It seems that the default connection pool of hibernate has a bug in database connection management. It does not check whether the connection is valid, so exceptions may occur.
I searched for information about how to configure MySql in hibernate on the Internet and found that MySQL had an eight-hour problem. That is, if the system is not accessed for more than eight hours, MySQL will close the idle connection, however, Hibernate does not check whether the connection is valid, and the system cannot connect to the database.
After reading a lot of information, we can basically see that there is a problem with database connection management. We use hibernate3, and hibernate's default connection pool is used for database configuration, switch to the proxool connection pool.
Refer to the following:
Http://www.360doc.com/content/08/0101/10/53523_938529.shtml
3. proxool connection pool
Proxool is different from c3p0 and DBCP. It generates a connection by itself, so the connection information is stored in the proxool configuration file. When you use it, you need to add the proxool-0.8.3.jar to classespath. Configuration example:
Hibernate. cfg. xml
<? XML version = "1.0" encoding = "UTF-8"?> <! Doctype hibernate-configuration public "-// hibernate/hibernate configuration DTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
Compile the proxool configuration file proxoolconf. XML in the same directory of hibernate. cfg. xml. The configuration example of this file is as follows:
Proxoolconf. xml
<? XML version = "1.0" encoding = "UTF-8"?> <! -- The proxool configuration can be embedded within your own application's. anything outside the "proxool" tag is ignored. --> <something-else-entirely> <proxool> <alias> pool1 </alias> <! -- Proxool can only manage connections generated by itself --> <! -- Driver URL --> <! -- JDBC: mysql: // localhost: 3306/dbname? Useunicode = true & characterencoding = GBK --> <driver-URL>... </Driver-URL> <! -- Driver Class, eg. com. MySQL. JDBC. Driver --> <driver-class>... </Driver-class> <driver-Properties> <! -- Database username. For example, the value of EG. value is root --> <property name = "user" value = "... "/> <! -- Database Password. eg. value is root --> <property name = "password" value = ".... "/> </Driver-Properties> <! -- The proxool automatically detects the time interval (in milliseconds) of each connection status, and immediately recycles the idle connection, destroy timeout -->
According to the jar package added with proxool0.9.1 and configured, the test fails, and the exception of JDBC connection is reported, which is strange. A buddy and I followed the above configuration, but he passed it. After reading his configuration file, he found his hibernate. cfg. the database connection information is still configured in XML. This should not be needed because it is stored in proxool. configured in XML. Is it because of this, I also added the connection information for testing, the result is normal login, the system date is adjusted for a few days after the login test, and reported the exception at the beginning. Obviously, the connection pool I configured does not work. It's strange. My buddy put his hibernate. cfg. after the database connection configuration in XML is removed, the database can still run and run after the system time is adjusted. This indicates that the connection pool has taken effect and the problem is finally solved. However, our code is the same, and the configuration files are the same. Why does it not work for me? Very depressing. Is it a matter of character ?! No, my character should be OK, but the cruel reality is in front of me ...... No matter what it is, it's a little more noon. If you haven't eaten lunch yet, go to dinner.
I had a bowl of beef and chopped noodles in the Lanzhou noodle shop outside the school. When I came back, I thought about this problem, and I was so worried. After thinking for a while, I think it should be hibernate. cfg. XML and proxool. xml configuration file, so I copied the two configuration files from my buddy to my system and replaced them. Run through ...... Dizzy. I copied the content of the configuration file directly on the webpage, and there may be some character problems. In this way, the test is not reassuring, and the system is put on a small server for a period of time to see if there will be problems.
After running for a few days, the result is still normal.