Java 中的电子邮件服务引发 "out of memory" 错误
Email service in Java throws an "out of memory" error
我是 运行 后台电子邮件服务(在命令提示符下),它旨在保留 运行 并从队列 table 中提取记录进行处理。
这是我的 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, subject, 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();
请注意,您可以使用 "try with reousrces" 让事情自行关闭:
try (PreparedStatement statement = con1.prepareStatement(sql); ResultSet rs = statement.executeQuery())
比照。 Java 7 Automatic Resource Management JDBC (try-with-resources statement)
public void email() throws Exception {
String sql = "SELECT id,subject,recipient,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, subject, content, id);
}
} catch (Exception e) {
e.printStackTrace();
}
}
con1.close();
Thread.sleep(2000);
}
我是 运行 后台电子邮件服务(在命令提示符下),它旨在保留 运行 并从队列 table 中提取记录进行处理。
这是我的 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, subject, 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();
请注意,您可以使用 "try with reousrces" 让事情自行关闭:
try (PreparedStatement statement = con1.prepareStatement(sql); ResultSet rs = statement.executeQuery())
比照。 Java 7 Automatic Resource Management JDBC (try-with-resources statement)
public void email() throws Exception {
String sql = "SELECT id,subject,recipient,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, subject, content, id);
}
} catch (Exception e) {
e.printStackTrace();
}
}
con1.close();
Thread.sleep(2000);
}