Java OutOfMemoryError
我正在做一个时间表作为最后一年的项目。在过去的两天里,我遇到了一个OutOfMemory例外。我已经阅读了很多关于异常的内容,并试图通过-Xms和-Xmx选项增加分配的内存。这些似乎都不适合我 我分析了这个项目,发现hashmap对象和MySQL连接占用了最大的空间。我使用了静态连接,如下所示Java OutOfMemoryError,java,mysql,Java,Mysql,我正在做一个时间表作为最后一年的项目。在过去的两天里,我遇到了一个OutOfMemory例外。我已经阅读了很多关于异常的内容,并试图通过-Xms和-Xmx选项增加分配的内存。这些似乎都不适合我 我分析了这个项目,发现hashmap对象和MySQL连接占用了最大的空间。我使用了静态连接,如下所示 public final class Connector { private static Connector connector; Connection con; String driverName;
public final class Connector
{
private static Connector connector;
Connection con;
String driverName;
String dbname;
String username;
String password;
String connString;
private Connector(){
driverName = "com.mysql.jdbc.Driver";
dbname = "timegen";
username = "root";
password = "root";
connString = "jdbc:mysql://localhost:3306/" + dbname;
openConnection();
}
public void openConnection(){
try{
Class.forName(driverName);
con = DriverManager.getConnection(connString, username, password);
} catch(Exception e){
System.out.println(e);
}
}
public void terminateConnection(){
try{
con.close();
} catch(Exception e){
System.out.println(e);
}
}
public static Connector createConnection() {
if (connector == null){
connector = new Connector();
}
return connector;
}
public Connection getCon() {
return con;
}
public String getConnString() {
return connString;
}
public void setConnString(String connString) {
this.connString = connString;
}
}
这是名为MasterData的类的代码,该类由访问数据库的所有其他类扩展
public class MasterData{
static Connector con;
static Statement st;
MasterData(){
try {
con = Connector.createConnection();
st = con.getCon().createStatement();
} catch (SQLException ex) {
Logger.getLogger(MasterData.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Statement createStatement() throws SQLException{
Statement st = con.getCon().createStatement();
return st;
}
public void closeConnection(){
con.terminateConnection();
}
}
使用此函数的类的示例
public class Teacher extends MasterData{
int teacherid;
String teachername;
String subject;
String post;
@Override
public String toString() {
return "Teacher{" + "teacherid=" + teacherid + ", teachername=" + teachername + ",
post=" + post + ", subject=" + subject + '}';
}
public Teacher(int teacherid, String teachername,String subject, String post) {
this.teacherid = teacherid;
this.teachername = teachername;
this.subject = subject;
this.post = post;
}
public Teacher(String teachername) {
this.teachername = teachername;
}
public Teacher(){}
public String display(){
String s ="\nTeacher name = " + teachername
+ "\nSubject = " + subject
+ "\nPost = "+post;
return s;
}
public ArrayList<String> getSubjectTeachers(String s){
ArrayList<String> teachers = new ArrayList<String>();
try{
ResultSet rs = st.executeQuery("select teachername from teacher where
subject='"+s+"';");
while(rs.next()){
teachers.add(rs.getString(1));
}
}catch(Exception e){e.printStackTrace();}
return teachers;
}
public List<Teacher> getFree()
{
List<Teacher> lst = new ArrayList<Teacher>();
try{
ResultSet rs = st.executeQuery("select * from teacher where teacherid not
in(select classteacher from division where classteacher!=null)");
while(rs.next())
{
lst.add(new
Teacher(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getString(4)));
}
}catch(Exception e ){e.printStackTrace();}
return lst;
}
public int getTeacherid() {
return teacherid;
}
public void setTeacherid(int teacherid) {
this.teacherid = teacherid;
}
public String getTeachername() {
return teachername;
}
public void setTeachername(String teachername) {
this.teachername = teachername;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getPost() {
return post;
}
public void setPost(String post) {
this.post = post;
}
public boolean checkDuplicate(){
try{
ResultSet rs = st.executeQuery("select * from teacher where
teachername='"+teachername+"';");
if(rs.next())
return true;
}catch(Exception e){e.printStackTrace();}
return false;
}
public boolean insert(){
int t;
try{
t = st.executeUpdate("insert into teacher(teachername,subject,post)
values('"+teachername+"','"+subject+"','"+post+"');");
if(t!=0) return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
return false;
}
public boolean delete(){
int t;
try{
new AssignedTeacher().deleteTeacher(teacherid);
t = st.executeUpdate("delete from teacher where teacherid="+teacherid+";");
if(t!=0) return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
return false;
}
public boolean update(){
int t;
try{
t = st.executeUpdate("update teacher set teachername = '"+teachername+"',
subject='"+subject+"', post='"+post+"' where teacherid="+teacherid+";");
if(t!=0) return true;
}
catch(Exception e){
e.printStackTrace();
return false;
}
return false;
}
}
我的意图是为整个程序创建一个静态连接。它似乎工作得很好。但是这可能是问题的原因吗?看起来您创建的连接太多了 您可以在openConnection方法中验证连接是否可用 编辑: 在我看来,您之所以尝试实现,是因为有insert、delete、update和getSubjectTeachers方法。无论如何,这并不总是一个好主意。作为副作用,将为MasterData的每个实例创建新连接。静态连接con将被重新分配给新对象,但以前的连接永远不会关闭。MasterDatacreateStatement也是如此
此外,正如格里迪佛所指出的,确保HashMap没有以相同的方式重新分配。也尝试设置这些参数:
-XX:PermSize
-XX:MaxPermSize
如果每次查询数据库时只打开和关闭一个连接,会有帮助吗?不使用这两个类?这不是真的必要。你可以重复使用一些外部罐子吗?如果是这样的话,有几种很好的实现,例如,我将尝试一下。感谢you@SotiriosDelimanolis:我没有收到空指针异常。整个程序运行良好,直到我添加了更多函数。然后我开始使用OutOfMemory异常getter是否只是返回连接器的Connection con字段?让我们@AartiRajan我会要求您发布异常的完整堆栈跟踪。我看不出哪里会出现OutOfMemoryException。另外,您确定是SQL连接而不是您提到的HashMaps吗?每个占用了多少内存?看起来她已经尝试过了,并试图增加通过-Xms和-Xmx选项分配的内存。后续的OutOfMemoryErrors只是时间问题,因为代码中存在一些问题。此外,我不确定这是否是PermGen空间错误,因为静态对象仍然存储在堆中。