我正在后台(在命令提示符下)运行电子邮件服务,这是为了继续运行并在队列表中提取记录以进行处理.
这是我的Email.java:
public class Email {
MysqLConnect con=new MysqLConnect();
public PreparedStatement preparedStatement = null;
public Connection con1 = con.connect();
public Email() throws Exception {
}
//pick up queue and send email
public void email() throws Exception {
try{
while(true) {
String sql = "SELECT id,subject,recipient,content FROM emailqueue WHERE status='Pending' ";
PreparedStatement statement = con1.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
String subject = rs.getString("subject");
String recipient = rs.getString("recipient");
String content = rs.getString("content");
String id = rs.getString("id");
sendEmail(recipient,content,id);
}
}
}catch(Exception e){
e.printStackTrace();
}
con1.close();
Thread.sleep(2000);
}
//Schedule a service for picking email
public void schedule(){
Thread service;
service = new Thread(new Runnable() {
public void run() {
try {
System.out.println("Email service is ready");
email();
} catch (Exception e) {
e.printStackTrace();
}
}
});
service.start();
}
public void sendEmail(String recipient,String subject,String content,String id) {
try {
//final String fromEmail = "lordjesus0371@gmail.com"; //requires valid gmail id
// final String password = "htasia123"; // correct password for gmail id
// InitialContext ctx = new InitialContext();
String host = get_attributevalue("MAIL_SERVER");
String port = get_attributevalue("MAIL_PORT");
final String senderaddress = get_attributevalue("SENDER_ADDRESS");
final String password = get_attributevalue("MAIL_PASSWORD");
System.out.println("Please Wait,sending email...");
/*Setup mail server */
Properties props = new Properties();
props.put("mail.smtp.host",host); //SMTP Host
props.put("mail.smtp.port",port); //TLS Port
props.put("mail.smtp.auth","true"); //enable authentication
props.put("mail.smtp.starttls.enable","true"); //enable STARTTLS
//create Authenticator object to pass in Session.getInstance argument
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderaddress,password);
}
};
Session session = Session.getInstance(props,auth);
session.setDebug(true);
// Define message
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(senderaddress));
message.addRecipients(Message.RecipientType.TO,InternetAddress.parse(recipient));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(content);
Transport.send(message);
delivered(id);
System.out.print("Email sent");
} catch (Exception e) {
System.out.println(e.getMessage());
try{
error(id);
} catch (sqlException e1) {
e1.printStackTrace();
}
}
}
在我的Main方法中:
public static void main(String[] args) throws Exception {
Email runEmailService=new Email();
runEmailService.schedule();
}
Exception in thread "Thread-1" java.lang.OutOfMemoryError: Java heap space
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Thread-1"
并且程序停止运行.
有没有一种方法可以防止这种情况的发生,使我的程序继续运行?
最佳答案
语句和结果集资源可能还没有被释放,并且因为您没有关闭它们而被保存在内存中.
考虑在while(rs.next())循环之后关闭它们:
rs.close();
statement.close();
请注意,您可以使用“尝试使用reousrces”来让事物自行关闭:
try (PreparedStatement statement = con1.prepareStatement(sql); ResultSet rs = statement.executeQuery())
cf. Java 7 Automatic Resource Management JDBC (try-with-resources statement)
public void email() throws Exception {
String sql = "SELECT id,content FROM emailqueue WHERE status='Pending' ";
while (true) {
try (PreparedStatement statement = con1.prepareStatement(sql); ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
String subject = rs.getString("subject");
String recipient = rs.getString("recipient");
String content = rs.getString("content");
String id = rs.getString("id");
sendEmail(recipient,id);
}
} catch (Exception e) {
e.printStackTrace();
}
}
con1.close();
Thread.sleep(2000);
}