实验思路:
这个是我写的一个测试线程数量的程序
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 1689019
NOW ACTIVITY THREAD NUMBER IS 6
FREE MEMORY IS ---------------------- > 19279
TOTAL MEMORY IS --------------- > 145920
MAX MEMORY IS ----------------- > 908288
NOW THE THREADS NUMBER IS 2239629
NOW ACTIVITY THREAD NUMBER IS 6
FREE MEMORY IS ---------------------- > 112022
TOTAL MEMORY IS --------------- > 268800
MAX MEMORY IS ----------------- > 908288
NOW THE THREADS NUMBER IS 2835575
NOW ACTIVITY THREAD NUMBER IS 6
FREE MEMORY IS ---------------------- > 90645
TOTAL MEMORY IS --------------- > 275968
MAX MEMORY IS ----------------- > 908288
NOW ACTIVITY THREAD NUMBER IS 6
- FREE MEMORY IS ---------------------- > 79341
TOTAL MEMORY IS --------------- > 284672
MAX MEMORY IS ----------------- > 908288
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进行垃圾回收啊。