• Java中的堆内存设置对线程创建数的影响以及-Xss参数的记录


    Java的线程对象是存储在堆上的,所以,能够创建多少个线程,受到堆空间的大小限制,同时也受到每个线程的大小的限制,假如线程对象内部有一个非常大的数组字段,那就非常影响能够创建的线程的大小

    我们的例子:

    class Task implements Runnable {
        //5M堆内存 128k的情况下,最多创建31个线程就挂了
    
        byte[] bytes = new byte[1024 * 128];
    
        @Override
        public void run() {
            while (true) {
                try {
                    bytes[0] = 1;
                    Thread.sleep(10_100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    线程对象内部持有一个数组字段,这个数组的大小是128k,我们的测试代码:

    public static void threadTest3() {
            int count = 1;
            try {
                while (true) {
    
                    Thread thread = new Thread(new Task());
                    thread.start();
                    System.out.println("==============================================" + count++);
                }
            } catch (Throwable e) {
                System.out.println(count);
                e.printStackTrace();
            }
    
        }
    

    运行测试的时候,我们将堆的内存设置的小一些:

    -Xmx5m -Xms5m XX:+PrintGC -XX:-PrintGCDetails

    输出的日志如下:

    "C:Program FilesJavajdk1.8.0_152injava.exe" -Xmx5m -Xms5m -XX:+PrintGC -XX:-PrintGCDetails  com.jiaoyiping.baseproject.concurrent.ThreadTest
    [GC (Allocation Failure)  1024K->732K(5632K), 0.0006644 secs]
    [GC (Allocation Failure)  1746K->1023K(5632K), 0.0012964 secs]
    [GC (Allocation Failure)  1818K->1417K(5632K), 0.0005073 secs]
    [GC (Allocation Failure)  2441K->1546K(5632K), 0.0008099 secs]
    [GC (Allocation Failure)  2570K->1773K(5632K), 0.0009678 secs]
    ==============================================1
    [GC (Allocation Failure)  2752K->2046K(5632K), 0.0012278 secs]
    ==============================================2
    ==============================================3
    ==============================================4
    ==============================================5
    ==============================================6
    ==============================================7
    ==============================================8
    [GC (Allocation Failure)  2962K->3022K(5632K), 0.0007815 secs]
    ==============================================9
    ==============================================10
    ==============================================11
    ==============================================12
    ==============================================13
    ==============================================14
    ==============================================15
    [GC (Allocation Failure)  3938K->3950K(5632K), 0.0005197 secs]
    [Full GC (Ergonomics)  3950K->3132K(5632K), 0.0098480 secs]
    ==============================================16
    ==============================================17
    ==============================================18
    ==============================================19
    ==============================================20
    ==============================================21
    ==============================================22
    [GC (Allocation Failure)  4090K->4220K(5632K), 0.0004522 secs]
    [Full GC (Ergonomics)  4220K->3975K(5632K), 0.0085720 secs]
    ==============================================23
    ==============================================24
    ==============================================25
    ==============================================26
    ==============================================27
    ==============================================28
    ==============================================29
    [Full GC (Ergonomics)  4920K->4876K(5632K), 0.0110795 secs]
    [Full GC (Allocation Failure)  4876K->4856K(5632K), 0.0086577 secs]
    ==============================================30
    [Full GC (Ergonomics)  5015K->4985K(5632K), 0.0025122 secs]
    [Full GC (Allocation Failure)  4985K->4985K(5632K), 0.0022044 secs]
    31
    java.lang.OutOfMemoryError: Java heap space
    	at com.jiaoyiping.baseproject.concurrent.Task.<init>(ThreadTest.java:105)
    	at com.jiaoyiping.baseproject.concurrent.ThreadTest.threadTest3(ThreadTest.java:74)
    	at com.jiaoyiping.baseproject.concurrent.ThreadTest.main(ThreadTest.java:17)
    [Full GC (Ergonomics)  5118K->4995K(5632K), 0.0108311 secs]
    [Full GC (Ergonomics)  5107K->5029K(5632K), 0.0034520 secs]
    [Full GC (Ergonomics)  5107K->5058K(5632K), 0.0034841 secs]
    [Full GC (Ergonomics)  5107K->5064K(5632K), 0.0032645 secs]
    [Full GC (Ergonomics)  5107K->5097K(5632K), 0.0034425 secs]
    [Full GC (Ergonomics)  5107K->5107K(5632K), 0.0030512 secs]
    [Full GC (Ergonomics)  5107K->5107K(5632K), 0.0027000 secs]
    [Full GC (Ergonomics)  5109K->5109K(5632K), 0.0026329 secs]
    [Full GC (Ergonomics)  5111K->5111K(5632K), 0.0026942 secs]
    [Full GC (Ergonomics)  5113K->5113K(5632K), 0.0024612 secs]
    [Full GC (Ergonomics)  5116K->5116K(5632K), 0.0028061 secs]
    [Full GC (Ergonomics)  5118K->5118K(5632K), 0.0027730 secs]
    [Full GC (Ergonomics)  5119K->5119K(5632K), 0.0039374 secs]
    [Full GC (Allocation Failure)  5119K->5118K(5632K), 0.0037878 secs]
    [Full GC (Ergonomics)  5119K->5119K(5632K), 0.0031486 secs]
    [Full GC (Allocation Failure)  5119K->5119K(5632K), 0.0028138 secs]
    

    当创建了30个线程的时候,就出现了堆内存的溢出

    如果将bytes的值改变为56K呢,可以创建70个线程

    -Xss影响的是栈的深度(比如栈的深度大的话,能够递归调用的次数就越多)
    我们构造出来递归调用的例子,用来测试-Xss参数对递归调用的次数的影响

     public static void threadTest4() {
            try {
                add(0);
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
    
        static int add(int count) {
            System.out.println("invoke count" + (count + 1));
            return add(count + 1);
        }
    

    当-Xss设置为128k的时候:

    当-Xss设置为256K的时候:

    jvm推荐的-Xss设置最少是108k,小于108K的时候,结果是不可预料的

    5k-64k 无法创建虚拟机:

    4k和以下很大的数值:

    64K- 108K

    这个值默认是1M我们一般不需要修改,值需要知道-Xss和栈的深度有关即可,通过以上的例子我们得到以下结论:堆内存的大小,和线程对象本身的大小,影响能够创建的线程的个数,-Xss影响栈的深度

    除了Java虚拟机之外,操作系统也会对能创建多少个进程和线程进行限制

    通过两个文件我们可以查看和修改这些限制数:
    最大的PID
    /proc/sys/kernel/threads-max

    最多的线程数:
    /proc/sys/kernel/pid_max

  • 相关阅读:
    纪中第三天
    纪中第一天
    图片验证码的实现
    使用监听器解决路径问题
    log4j测试示例
    redis示例
    kafka示例
    CSRF verification failed. Request aborted.
    TemplateDoesNotExist
    创建 django 项目命令
  • 原文地址:https://www.cnblogs.com/jiaoyiping/p/10345462.html
Copyright © 2020-2023  润新知