3

jvm系列

Xss与线程个数

Xss越大,每个线程的大小就越大,占用的内存越多,能容纳的线程就越少;Xss越小,则递归的深度越小,容易出现栈溢出 java.lang.StackOverflowError。减少局部变量的声明,可以节省栈帧大小,增加调用深度。

/**
 * -Xss128K   deep of calling = 675
 * -Xss256K   deep of calling = 1686
 *
 * Xss越大,每个线程的大小就越大,占用的内存越多,能容纳的线程就越少
 * Xss越小,则递归的深度越小,容易出现栈溢出  java.lang.StackOverflowError
 * 减少局部变量的声明,可以节省栈帧大小,增加调用深度
 */
public class XssDemo {
    private static int count=0;
    public static void recursion(){
        //减少局部变量的声明,可以节省栈帧大小,增加调用深度
        long a=1,b=2,c=3,d=4,e=5,f=6,q=7,x=8,y=9,z=10;
        count++;
        recursion();
    }
    public static void main(String args[]){
        try{
            recursion();
        }catch(Throwable e){
            System.out.println("deep of calling = "+count);
            e.printStackTrace();
        }
    }
}

java线程数决定因素

JVM中可以生成的最大数量由JVM的堆内存大小、Thread的Stack内存大小、系统最大可创建的线程数量(Java线程的实现是基于底层系统的线程机制来实现的,Windows下_beginthreadex,Linux下pthread_create)三个方面影响。

具体数量可以根据Java进程可以访问的最大内存(32位系统上一般2G)、堆内存、Thread的Stack内存来估算。

 (MaxProcessMemory - JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Number of threads
  • MaxProcessMemory : 进程的最大寻址空间

  • JVMMemory : JVM内存

  • ReservedOsMemory : 保留的操作系统内存,如Native heap,JNI之类,一般100多M

  • ThreadStackSize : 线程栈的大小,jvm启动时由Xss指定

/**
 * -XX:+PrintFlagsFinal
 * maxHeapSize 289406976 byte
 * maxPermSize 85983232 byte
 * threadStackSize 1024 byte
 *
 * JVM中可以生成的最大数量由JVM的堆内存大小、Thread的Stack内存大小、系统最大可创建的线程数量
 * (Java线程的实现是基于底层系统的线程机制来实现的,Windows下_beginthreadex,Linux下pthread_create)三个方面影响。
 * 具体数量可以根据Java进程可以访问的最大内存(32位系统上一般2G)、堆内存、Thread的Stack内存来估算。
 *
 * (MaxProcessMemory - JVMMemory – ReservedOsMemory) / (ThreadStackSize) = Number of threads
 * MaxProcessMemory : 进程的最大寻址空间
 * JVMMemory : JVM内存
 * ReservedOsMemory : 保留的操作系统内存,如Native heap,JNI之类,一般100多M
 * ThreadStackSize : 线程栈的大小,jvm启动时由Xss指定
 *
 * http://www.rigongyizu.com/jvm-max-threads/
 */
public class TestMaxThread {
    public static final int BATCH_SIZE = 2000;
    public static void main(String[] args){
        List<Thread> threads = new ArrayList<Thread>();
        try{
            for(int i=0;i<=100*1000;i+= BATCH_SIZE){
                long start = System.currentTimeMillis();
                createThread(threads,BATCH_SIZE);
                long end = System.currentTimeMillis();
                Thread.sleep(1000);
                long delay = end - start;
                System.out.printf("%,d threads: Time to create %,d threads was %.3f seconds %n", threads.size(), BATCH_SIZE, delay / 1e3);
            }
        }catch(Throwable e){
            System.out.println("After creating "+ threads.size()+" threads");
            e.printStackTrace();
        }
    }
    private static void createThread(List<Thread> threads,int num){
        for(int i=0;i<num;i++){
            Thread t = new Thread(new Runnable(){
                @Override
                public void run() {
                    try{
                        while (!Thread.interrupted()){
                            Thread.sleep(1000);
                        }
                    }catch (InterruptedException e){
                    }
                }
            });
            t.setDaemon(true);
            t.setPriority(Thread.MIN_PRIORITY);
            threads.add(t);
            t.start();
        }
    }
}

codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...