【问题标题】:What is actual number of threads in a java process?java进程中的实际线程数是多少?
【发布时间】:2015-10-13 01:46:44
【问题描述】:

背景

  • 在下面的代码中,创建并启动了“a”线程。
  • run 方法包含一个无限循环。
  • 在循环中,成员变量“prod”会在每个特定时间间隔后重新分配一个新配置的对象。
  • 配置基于一个 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 命令显示这么多“线程”的原因是什么?

为什么线程的数量会随着时间的推移而增加,从而导致内存使用量增加?

【问题讨论】:

  • 您是否使用 JProfile 或 VisualVM 之类的工具进行了仔细检查,以确保您的 bash 命令执行您认为的操作?
  • 这是一个 Amazon EC2 盒子。我现在知道是否可以安装类似的东西来仔细检查。我尝试在 mac 上模拟类似的东西并检查
  • 其中一个线程是您的 main() 线程,其中之一是您的主线程创建的线程。其余的是 JVM 的实现细节。 Java 语言规范或 JVM 规范中没有任何内容说明会有多少。确切的数字在不同的 JVM、不同的操作系统上可能不同,并且可能在进程生命周期的不同时间。
  • 是的,我知道数字 2。但数字 22 或 ~70 是我所关心的。此外,这大约 70 个是在该计划最初启动后的不同日期生成的,其中一些已经超过一个月没有消失。
  • JVisualm 是检验这一点的唯一方法。附加到活进程,你会看到有多少线程以及它们在做什么

标签: java multithreading memory memory-leaks


【解决方案1】:

问题是对所使用的库类的处理不当。我们使用了kafka.javaapi.producer.Producer,并且在刷新配置json文件之前没有调用方法close()。这导致了非常不可预测的行为。我们还删除了线程部分,因为只需 main 线程就足以执行任务,而不是陷入并发开销。

【讨论】:

    猜你喜欢
    • 2015-12-06
    • 2021-09-01
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 2022-12-29
    相关资源
    最近更新 更多