纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

jvm线程栈空间内存分配 详谈jvm线程栈空间内存分配位置

NetWhite   2021-09-13 我要评论
想了解详谈jvm线程栈空间内存分配位置的相关内容吗NetWhite在本文为您仔细讲解jvm线程栈空间内存分配的相关知识和一些Code实例欢迎阅读和指正我们先划重点:jvm线程栈,空间内存分配,分配内存下面大家一起来学习吧

jvm线程栈空间内存分配位置

jvm的线程栈申请的内存空间属于堆外内存是向操作系统申请的也不是JVM直接内存虽然类似

JVM能创建的线程数需要的内存不是JVM运行内存堆内存直接内存而是操作系统剩余的可用内存这个也决定了能创建的线程数如果内存不够用创建线程的时候便会出现内存溢出的错误

在操作系统的可用内存不足的情况下想要创建更多的线程可以考虑减少线程栈的空间大小(-Xss)但是不建议过小栈尝试减小容易栈溢出错误

--------------------------分割线--------------------------

后来有次早上5点睡不着起床做了个测试验证在这里补充下这个测试说明当时只是发了个朋友圈过得有点久了现在我也只从手机上找到几张图片贴上来:

JVM配置如下

设置最大堆10m线程栈大小10m直接内存5m

创建1000条线程调用10w次函数(调用次数再过多栈深不够就溢出了)疯狂压栈但不出栈(递归调用)然后看内存物理内存占用7g多有次是5g多没有堆溢出也没有直接内存溢出说明线程栈内存在堆外分配不属于堆内存(线程对象还是分配在堆内存空间)也不属于直接内存部分

测试截的一些图片如下

JVM配置

main方法创建1条线程并运行:

main方法创建1000条线程并运行:

测试代码

/**
 * @Auther: 许晓东
 * @Date: 19-8-3 05:14
 * @Description:
 */
public class ThreadStackTest {
    static Map<Integer, Thread> map = new HashMap<>();
    static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                recursive(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
 
    private static void recursive(int num) throws InterruptedException {
        if (num == 20000) {
            Thread.sleep(Integer.MAX_VALUE);
        }else {
            recursive(++num);
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        System.gc();
        int nums = 1000;
        //int nums = 1;
        for (int i = 0; i < nums; i++) {
            map.put(i, new Thread(runnable));
        }
 
        for (Thread thread :
                map.values()) {
            thread.start();
        }
 
        System.out.println(String.format("创建%d条线程后gc情况:", nums));
        System.gc();
        Thread.sleep(Integer.MAX_VALUE);
    }
}

jvm栈大小设置

1、栈内存大小设置

栈内存为线程私有的空间每个线程都会创建私有的栈内存栈空间内存设置过大创建线程数量较多时会出现栈内存溢出StackOverflowError同时栈内存也决定方法调用的深度栈内存过小则会导致方法调用的深度较小如递归调用的次数较少

-Xss:如-Xss128k

通常只有几百K

决定了函数调用的深度

每个线程都有独立的栈空间

局部变量、参数 分配在栈上

2、递归调用

package com.thread.study; 
public class Stack {
  private static int count=0;
  public static void recursion(long a,long b,long c){
   long e=1,f=2,g=3,h=4,i=5,k=6,q=7,x=8,y=9,z=10;
   count++;
   recursion(a,b,c);
  }
  public static void main(String args[]){
   try{
    recursion(0L,0L,0L);
   }catch(Throwable e){
    System.out.println("deep of calling = "+count);
    e.printStackTrace();
   }
  } 
}
  • -Xss128k:deep of calling = 306
  • -Xss256k:deep of calling = 761

以上为个人经验希望能给大家一个参考也希望大家多多支持


相关文章

猜您喜欢

  • Java 基础之NIO 学习 Java 基础之NIO 学习详解

    想了解Java 基础之NIO 学习详解的相关内容吗IT__learning在本文为您仔细讲解Java 基础之NIO 学习的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java,基础,JavaNIO,学习下面大家一起来学习吧..
  • 枚举类中valueOf用法 java 枚举类中的valueOf用法说明

    想了解java 枚举类中的valueOf用法说明的相关内容吗lamdaxu在本文为您仔细讲解枚举类中valueOf用法的相关知识和一些Code实例欢迎阅读和指正我们先划重点:java,枚举类,valueOf用法下面大家一起来学习吧..

网友评论

Copyright 2020 www.sopisoft.net 【绿软下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式