• 关于JAVA的线程问题


    实验思路:
    这个是我写的一个测试线程数量的程序
    1. import java.util.Date;
    2. import java.util.HashSet;
    3. import java.util.Map;
    4. import java.util.Set;
    5. public class MyThreadTest {
    6. public static void main(String[] args){
    7. boolean flag = true;
    8. Set<Long>threadSet = new HashSet<Long>();
    9. long last = -1;
    10. long now = 0;
    11. Runtime runtime = Runtime.getRuntime();
    12. while(true){
    13. MyThread thread = new MyThread(flag);
    14. thread.start();
    15. threadSet.add(thread.getId());
    16. if(last == now){
    17. System.out.println("PAY ATTATION ! THE MOST THREADS IS " + threadSet.size());
    18. flag = false;
    19. }else{
    20. last = now;
    21. now = threadSet.size();
    22. }
    23. if(System.currentTimeMillis() % 3000 == 0){
    24. System.out.println("NOW THE THREADS NUMBER IS " + threadSet.size());
    25. System.out.println("NOW ACTIVITY THREAD NUMBER IS " + Thread.getAllStackTraces().size());
    26. if(System.currentTimeMillis() % 10000 == 0){
    27. System.out.println("FREE MEMORY IS ---------------------- > " + runtime.freeMemory() / 1024);
    28. System.out.println("TOTAL MEMORY IS --------------- > " + runtime.totalMemory() / 1024);
    29. System.out.println("MAX MEMORY IS ----------------- > " + runtime.maxMemory() / 1024);
    30. }
    31. }
    32. }
    33. }
    34. }
    35. class MyThread extends Thread{
    36. public MyThread(final boolean flag) {
    37. Runnable runnable = new Runnable() {
    38. public void run() {
    39. while (flag) {
    40. new Date();
    41. }
    42. }
    43. };
    44. }
    45. }
    思路是,自定义一个线程类,类中启动一个Runnable,在run()函数中做一些方法,主类中定义一个集合set,为存放新生成的线程的id,以便判断新的线程是否还能够继续生成的。之后每隔3秒输出一次线程总数和现在的活动线程数,并在10秒中输出jvm剩余的内存、申请的内存和最大内存数。

    实验结果:
    1. NOW THE THREADS NUMBER IS 1689019
    2. NOW ACTIVITY THREAD NUMBER IS 6
    3. FREE MEMORY IS ---------------------- > 19279
    4. TOTAL MEMORY IS --------------- > 145920
    5. MAX MEMORY IS ----------------- > 908288
    6. NOW THE THREADS NUMBER IS 2239629
    7. NOW ACTIVITY THREAD NUMBER IS 6
    8. FREE MEMORY IS ---------------------- > 112022
    9. TOTAL MEMORY IS --------------- > 268800
    10. MAX MEMORY IS ----------------- > 908288
    11. NOW THE THREADS NUMBER IS 2835575
    12. NOW ACTIVITY THREAD NUMBER IS 6
    13. FREE MEMORY IS ---------------------- > 90645
    14. TOTAL MEMORY IS --------------- > 275968
    15. MAX MEMORY IS ----------------- > 908288

    16. NOW ACTIVITY THREAD NUMBER IS 6
    17. FREE MEMORY IS ---------------------- > 79341
    18. TOTAL MEMORY IS --------------- > 284672
    19. MAX MEMORY IS ----------------- > 908288
    20. NOW THE THREADS NUMBER IS 3131343

    这是我截取的一写时间的输出。可以看到,我的活动线程数维持在6不变,代表我的cpu最多能同时运行的线程总数,通过数量和时间观察可以看到一个很奇怪的现象,
    那就是:有些时候,随着线程生成的总数的增加,其剩余的内存数目反而可能增长。
    我的猜想是:虚拟机在内存不足的时间,能够自动清理掉一些不用的线程,释放出内存容量给程序运行,在运行这个程序的时候我的cpu一直是接近100%。内存因为jvm的限制一直在80%左右徘徊。我没有办法控制jvm的垃圾回收不运行,所以这个实验可以说是阶段性失败。所以得出的 
    这是我截取的一写时间的输出。可以看到,我的活动线程数维持在6不变,代表我的cpu最多能同时运行的线程总数,通过数量和时间观察可以看到一个很奇怪的现象,
    那就是:有些时候,随着线程生成的总数的增加,其剩余的内存数目反而可能增长。
    我的猜想是:虚拟机在内存不足的时间,能够自动清理掉一些不用的线程,释放出内存容量给程序运行,在运行这个程序的时候我的cpu一直是接近100%。内存因为jvm的限制一直在80%左右徘徊。我没有办法控制jvm的垃圾回收不运行,所以这个实验可以说是阶段性失败。所以得出的结论也只是猜想。
    PS:
    java.lang.OutOfMemoryError: GC overhead limit exceeded
    我一开始长时间运行程序的时候,还出现了这种错误,网上查是jvm gc行为中超过98%以上的时间去释放小于2%的堆空间时会报这个错误。看来启动多线程,消耗过多内存,肯定是会出现jvm进行垃圾回收啊。




  • 相关阅读:
    docker学习笔记及hadoop集群搭建
    Zookeeper+Kafka+Storm+HDFS实践
    zookeeper集群搭建
    scala学习笔记——特质
    scala学习笔记-集合
    scala学习笔记-隐式转换和隐式参数
    RDD 重新分区,排序 repartitionAndSortWithinPartitions
    scala学习笔记——操作符
    JAVA基础系列(一) 概述与相关概念
    网络收藏夹
  • 原文地址:https://www.cnblogs.com/sober-reflection/p/4057084.html
Copyright © 2020-2023  润新知