java运行一段时间变慢_java - Tomcat的Spring-MVC项目在重启一段时间后变卡

最近更新了程序之后,发现网页在tomcat重启一阵子之后变得异常的卡。不知道为什么。发现了好多内存泄漏的警告,觉得是不是因为不正常的关闭导致内存不足呢,就试了几个方法。

最先试着把tomcat的context.xml里面设置缓存最大值,貌似设到了100000,启动后发现速度不错,但过了一段时间又卡得不得了了。

再之后把服务器的内存调大了,问题还是照样出现。而且每次系统的缓存只会越来越多,不会减少。

d7b182bbf21f74225dcbb1021cf27aae.png

上网看了一些类似问题的回答,有人说是java获取数据库的效率不高而造成的,但是我觉得我这个问题应该不是出在这,因为有很多需要获取数据库的函数代码都变,以前就没有出现过这种问题,为什么现在变成这样呢?不过最近倒是有一些改动,例如添加了两个TimerTask。倒觉得应该问题不回出在这里吧。

package x.xx.xxx;

import java.util.Calendar;

import java.util.Date;

import java.util.List;

import java.util.Timer;

import java.util.TimerTask;

import javax.annotation.Resource;

import org.apache.log4j.Logger;

import x.xx.xxx.ManagementStation;

import x.xx.xxx.ManagementStationService;

/**

* 源代码来自《java定时任务,每天定时执行任务》

* http://www.cnblogs.com/cvst/articles/5818233.html

*

*/

public class TimerManager {

@Resource

RemoteControlController remoteControlController;

@Resource

ManagementStationService managementStationService;

@Resource

ControllerStatusController controllerStatusController;

// 时间间隔

private static final long PERIOD_DAY = 24 * 60 * 60 * 1000;

private static final int START_TIME = 1;

public void initTimerManager() {

Calendar calendar = Calendar.getInstance();

/*** 定制每日1:00执行方法 ***/

calendar.set(Calendar.HOUR_OF_DAY, START_TIME);

calendar.set(Calendar.MINUTE, 0);

calendar.set(Calendar.SECOND, 0);

Date date = calendar.getTime(); // 第一次执行定时任务的时间

Date date2 = calendar.getTime();

// 如果第一次执行定时任务的时间 小于 当前的时间

// 此时要在第一次执行定时任务的时间加一天,以便此任务在下个时间点执行。如果不加一天,任务会立即执行。

if (date.before(new Date())) {

date = this.addDay(date, 1);

}

Timer timer = new Timer();

Timer timer2 = new Timer();

UpdateDailyEletricPowerTimerTask task = new UpdateDailyEletricPowerTimerTask();

// 安排指定的任务在指定的时间开始进行重复的固定延迟执行。

timer.schedule(task, date, PERIOD_DAY);

UpdateLampStatusTimerTask task2 = new UpdateLampStatusTimerTask();

timer2.schedule(task2, date2, PERIOD_DAY);

}

// 增加或减少天数

public Date addDay(Date date, int num) {

Calendar startDT = Calendar.getInstance();

startDT.setTime(date);

startDT.add(Calendar.DAY_OF_MONTH, num);

return startDT.getTime();

}

public class UpdateDailyEletricPowerTimerTask extends TimerTask {

private Logger log = Logger.getLogger(UpdateLampStatusTimerTask.class);

@Override

public void run() {

try {

/**

* 查询前昨两天日冻结正向有功总电量

*/

Calendar now = Calendar.getInstance();

int year = now.get(Calendar.YEAR) - 2000;

int month = now.get(Calendar.MONTH) + 1;

int day = now.get(Calendar.DATE);

remoteControlController.dailyPositiveElectricPowerCollecting(year, month, day);

} catch (Exception e) {

log.info("-------------NFDFlightDataTimerTask解析信息发生异常--------------");

}

}

}

public class UpdateLampStatusTimerTask extends TimerTask {

private Logger log = Logger.getLogger(UpdateLampStatusTimerTask.class);

@Override

public void run() {

try {

/**

* 更新全部灯具状态

*/

List mlist = managementStationService.getManagementStationList();

StringBuffer temp=new StringBuffer("");

for(ManagementStation m:mlist) temp.append(m.getMid()+",");

String[] arr = temp.toString().split(",");

boolean realTime = false;

controllerStatusController.UpdateControllerStatus(arr,realTime);

} catch (Exception e) {

log.info("-------------UpdateLampStatusTimerTask解析信息发生异常--------------");

}

}

}

不过系统变得死卡死卡的的时候其实是开启thread和进行socket通讯之后。

不过不知道问题出在前置机于客户端的通讯那,还是我这边的系统程序问题,下面是系统接收返回信息的线程,请各位大虾过目过目,谢谢。

private Status GetReturnedInfo(int frame_no) throws Exception{

FrameController.addFrameToSendingQueue(frame_no);

Status status=new Status();

long beginTime = System.currentTimeMillis();

boolean over_runtime = false;

/**

* 如果超过最大接收时间RUNTIME_MAX就直接把接收到的信息返回页面

* 其他的报文继续在后台进行接收

*/

while(FrameController.getExpectReutrnedFrameAmount(frame_no) != 0){

Thread.sleep(1000);

long nowTime = System.currentTimeMillis();

over_runtime = nowTime - beginTime > RUNTIME_MAX? true : false;

if(over_runtime) break;//超时跳出

}

List return_frames = FrameController.GetReturnedFrame(frame_no);

List olist= new ArrayList();

if(return_frames !=null){

for(byte[] return_frame:return_frames){

List olisttmp = parseFrontEndMsg(return_frame);

if(olisttmp != null)

olist.addAll(olisttmp);

}

status.setCode(1);

}else{

status.setCode(0);

}

status.setList(olist);

if(!over_runtime){

FrameController.RecallFrameNo(frame_no);

}else{

/**

* 后台处理超时没有返回的报文

*/

final int tmp_frame_no = frame_no;

new Thread(new Runnable(){

@Override

public void run() {

int frame_no_in_the_thread = tmp_frame_no;//FIXME 有点问题:如果tmp_frame_no在运行到这行时被其他线程改变了,怎么办?

long beginTime = System.currentTimeMillis();

boolean over_runtime = false;

int lastExpectReutrnedFrameAmount = FrameController.getExpectReutrnedFrameAmount(frame_no_in_the_thread);

while(FrameController.getExpectReutrnedFrameAmount(frame_no_in_the_thread) != 0){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

long nowTime = System.currentTimeMillis();

over_runtime = nowTime - beginTime > BG_RUNTIME_MAX? true : false;

if(over_runtime) {

//再超时便强制回收帧序号,虽然暂时和直接回收没有区别。

FrameController.CompulsivelyRecallFrameNo(frame_no_in_the_thread);

return;

}

/**

* 如果该帧返回报文有继续更新,重置beginTime

* 主要用于十分花时间的多报文返回操作RUNTIME_MAX的话就直接返回到页面。

* 相当于如果下一个报文返回间隔的时间大于RUNTIME_MAX就强行关闭对该帧的返回报文的接收

*/

if(lastExpectReutrnedFrameAmount != FrameController.getExpectReutrnedFrameAmount(frame_no_in_the_thread)){

lastExpectReutrnedFrameAmount = FrameController.getExpectReutrnedFrameAmount(frame_no_in_the_thread);

beginTime = System.currentTimeMillis();

}

FrameController.RecallFrameNo(frame_no_in_the_thread);

}

}).start();

}

return status;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,错误信息表明数据源已关闭。这可能是由于以下原因之一导致的: 1. 数据库连接池中的连接已经关闭,但是应用程序仍然在尝试使用它们。 2. 数据库连接池配置不正确,导致连接池无法正常工作。 为了解决这个问题,可以尝试以下步骤: 1. 检查应用程序中是否有未关闭的数据库连接。可以使用JDBC API手动关闭连接,或者使用Spring框架等ORM工具自动管理连接。 2. 检查数据库连接池的配置是否正确。可以尝试使用默认配置,或者根据官方文档调整配置参数。 以下是一些可能有用的代码片段和参考链接: 1. 手动关闭JDBC连接的示例代码: ```java Connection conn = null; try { conn = DriverManager.getConnection(url, username, password); // 执行SQL语句等操作 } catch (SQLException e) { // 处理异常 } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { // 处理异常 } } } ``` 2. Spring Boot中使用Druid连接池的示例配置: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/house?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.druid.initial-size=5 spring.datasource.druid.max-active=20 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-wait=60000 spring.datasource.druid.time-between-eviction-runs-millis=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 spring.datasource.druid.validation-query=SELECT 1 FROM DUAL spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false spring.datasource.druid.pool-prepared-statements=true spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 spring.datasource.druid.filters=stat,wall,log4j spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值