Java線程與Xss

jvm系列java

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();
        }
    }
}
相關文章
相關標籤/搜索