背景
配置基于json对象,而json对象又使用配置文件
创建public class Producer extends Thread {
private long lastReadTime;
private long refreshInterval;
private String configFile;
private JSONObject configJson;
private MyProducer prod;
public StdInProducer (String filename) throws IOException {
this.configFile = filename;
this.refreshConfig();
}
public void refreshConfig() {
this.lastReadTime = System.currentTimeMillis();
this.configJson = new JSONObject(FileUtils.readFileToString(new File(this.configFile), "UTF-8"));
this.refreshInterval = this.confJsonObj.optLong("refreshInterval", 86400);
this.initializeProducer(configJson);
}
private void initializeProducer(JSONObject confJsonObj) {
//initialise producer using json object values
this.prod = // new MyProducer obj with settings from json obj
}
public void run() {
while(true) {
long currentTime = System.currentTimeMillis();
if(currentTime - this.lastReadTime > this.refreshInterval*1000) {
this.refreshConfig();
}
// Rest of the code
}
}
}
public static void main(String[] args) {
String configFilename = args[0];
Thread t = new Producer(configFilename);
t.start();
}
观察
Thread.activeCount()
显示输出为2
ps -aefL | grep producer | grep -v "grep" | wc -l
显示程序启动时最初运行的22个线程。
ps -aefL | grep producer
root 18498 1 18498 0 22 Jul22 ? 00:00:00 /usr/bin/java -cp producer-1.0.jar stdin.producer.Producer stdinConfig.json
root 18498 1 18499 0 22 Jul22 ? 00:00:00 /usr/bin/java -cp producer-1.0.jar stdin.producer.Producer stdinConfig.json
root 18498 1 18500 0 22 Jul22 ? 00:01:55 /usr/bin/java -cp producer-1.0.jar stdin.producer.Producer stdinConfig.json
root 18498 1 18501 0 22 Jul22 ? 00:01:55 /usr/bin/java -cp producer-1.0.jar stdin.producer.Producer stdinConfig.json
(由于空间限制,仅显示少数几行)
在程序初始运行约2个月后观察到问题,观察到盒子上的线程数为~70(使用ps命令)和" top"显示VIRT内存使用量为12 GB。
重新启动程序后,第23个线程被添加到上面的列表中 一天(24小时)后的线程,增加虚拟内存。所以问题出在那里,需要找出原因吗?
问题
程序创建了多少个线程?
是什么造成了这么多"线程"由ps命令显示?
为什么线程数随时间而增加,因此内存使用量会增加?
答案 0 :(得分:0)
问题是对使用的库类的处理不当。我们使用了kafka.javaapi.producer.Producer
,在刷新配置json文件之前,我们没有调用方法close()
。这导致了非常不可预测的行为。我们还删除了线程部分,因为只有main
线程足以执行任务而不是进入并发开销。