实验思路:
这个是我写的一个测试线程数量的程序
import java.util.Date;import java.util.HashSet;import java.util.Map;import java.util.Set;public class MyThreadTest {public static void main(String[] args){boolean flag = true;Set<Long>threadSet = new HashSet<Long>();long last = -1;long now = 0;Runtime runtime = Runtime.getRuntime();while(true){MyThread thread = new MyThread(flag);thread.start();threadSet.add(thread.getId());if(last == now){System.out.println("PAY ATTATION ! THE MOST THREADS IS " + threadSet.size());flag = false;}else{last = now;now = threadSet.size();}if(System.currentTimeMillis() % 3000 == 0){System.out.println("NOW THE THREADS NUMBER IS " + threadSet.size());System.out.println("NOW ACTIVITY THREAD NUMBER IS " + Thread.getAllStackTraces().size());if(System.currentTimeMillis() % 10000 == 0){System.out.println("FREE MEMORY IS ---------------------- > " + runtime.freeMemory() / 1024);System.out.println("TOTAL MEMORY IS --------------- > " + runtime.totalMemory() / 1024);System.out.println("MAX MEMORY IS ----------------- > " + runtime.maxMemory() / 1024);}}}}}class MyThread extends Thread{public MyThread(final boolean flag) {Runnable runnable = new Runnable() {public void run() {while (flag) {new Date();}}};}}
思路是,自定义一个线程类,类中启动一个Runnable,在run()函数中做一些方法,主类中定义一个集合set,为存放新生成的线程的id,以便判断新的线程是否还能够继续生成的。之后每隔3秒输出一次线程总数和现在的活动线程数,并在10秒中输出jvm剩余的内存、申请的内存和最大内存数。
实验结果:
NOW THE THREADS NUMBER IS 1689019NOW ACTIVITY THREAD NUMBER IS 6FREE MEMORY IS ---------------------- > 19279TOTAL MEMORY IS --------------- > 145920MAX MEMORY IS ----------------- > 908288NOW THE THREADS NUMBER IS 2239629NOW ACTIVITY THREAD NUMBER IS 6FREE MEMORY IS ---------------------- > 112022TOTAL MEMORY IS --------------- > 268800MAX MEMORY IS ----------------- > 908288NOW THE THREADS NUMBER IS 2835575NOW ACTIVITY THREAD NUMBER IS 6FREE MEMORY IS ---------------------- > 90645TOTAL MEMORY IS --------------- > 275968MAX MEMORY IS ----------------- > 908288NOW ACTIVITY THREAD NUMBER IS 6- FREE MEMORY IS ---------------------- > 79341
TOTAL MEMORY IS --------------- > 284672MAX MEMORY IS ----------------- > 908288NOW 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进行垃圾回收啊。