关于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进行垃圾回收啊。




原文地址:https://www.cnblogs.com/sober-reflection/p/4057084.html