美文网首页
5、JVM可以创建多少线程

5、JVM可以创建多少线程

作者: 霸体 | 来源:发表于2020-08-11 17:48 被阅读0次

线上java程序有事会遇到下面的问题:

OutOfMemoryError: unable to create new native thread

显然,创建java线程也是受到内存限制的,下面具体分析一下原因。

操作系统内存限制

32位操作系统的最大寻址空间是2^32个字节≈4G,一个32位进程最大可使用内存一般为2G(操作系统预留2G);
64位操作系统的寻址空间大大增加,但不是简单的2^64,寻址的位数实际还受限于CPU支持的最大物理地址宽度以及操作系统具体实现的限制,64位操作系统通常使用内存分页(每页一般为4KB)管理内存,内存分页管理有很大优势:

  • 交换内存(虚拟内存) x86 默认是 4KB 分页,操作系统可以将一些长久没有使用的内存页交换到外存上(一页只有4KB,写盘是非常快的),然后这些页就可以分配到别的地方使用,这样可以使得”内存容量”大增,而调度得好的话在性能上影响不大。
  • 延迟装载 现在一个游戏安装程序动辄上G,如果一次性装载完再执行,那等个几分钟才出安装界面也是正常的,实际上各种操作系统都用CPU的分页机制实现了延迟装载:装载程序时会在进程中建立内存页到可执行文件的映射,并将相应的页表项初始化为不可用状态,等执行到这个页的指令或访问这个页的数据时CPU就会触发缺页异常,操作系统到这个时候才根据映射把相应的指令或数据读到某页内存中并修改原来不可用的页表项指向它,然后重新执行导致异常的那条指令。所以即使是上G的程序也是瞬间装载的。
  • 共享内存 我们可以复制页表来实现进程间内存的共享。比如fork子进程就很快,因为只是复制了页表,所以子进程一开始是直接使用父进程内存的。再比如动态链接库,它们的指令所占内存页是在各个进程中共享的,所以公共动态链接库的繁荣可以减少内存占用。
  • copy on write 除了上面提到的缺页异常可实现延迟装载,还有个页保护异常可实现 copy on write,每个页表项有记录该页是否可写的标志位,当某进程fork一个子进程的时候会将所有可写的内存页设置为不可写,当子进程修改数据时会触发页保护异常,操作系统会将该页复制一份让子进程修改,父进程的数据完全不受影响。

x86_64 平台上的 Linux 理论上最多支持64TB的物理内存,单个进程理论上可用128TB的地址空间(高128TB被操作系统占用了),但受限于物理内存的限制,其中最多有64TB是物理内存,其余的理论上还可以用虚拟内存(swap分区)顶包.

下图是微软官网windows系统给的内存限制:


image.png

jvm进程的内存限制

对于32位操作系统,jvm进程的最大可用内存为2G;
对于64位操作系统,jvm进程理论可以获得跟物理内存一样大的内存,但是一般linux操作系统都会对进程进行资源限制, 如使用 ulimit -S xx 命令;

jvm可创建线程数量

公式: (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = 线程数

  • MaxProcessMemory 代表jvm进程最大可用的内存,32位操作系统为2G,64位操作系统取决于系统设置,如果未限制则默认等于物理内存;
  • JVMMemory 代表JVM的堆内存占用,此处也包含一些JVM堆外内存占用,如code-cachedirect-memory-bufferclass-compess-space等;
  • ReservedOsMemory 操作系统每个进程预留内存
  • ThreadStackSize 线程栈的大小,可以通过 -Xss 设置

参考资料


64位系统内存管理

linux下ulimit使用限制进程资源

相关文章

  • 5、JVM可以创建多少线程

    线上java程序有事会遇到下面的问题: 显然,创建java线程也是受到内存限制的,下面具体分析一下原因。 操作系统...

  • JVM面试详解

    1、JVM构成 Java栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类...

  • Java运行main方法,会有多少个线程

    上面的代码在运行时,会创建多少个线程呢?答案是5(6)个。 Java中有线程组的概念,一个线程组可以包含线程和线程...

  • JNI开发-线程操作

    JNI开发-线程操作 线程操作 JNIEnv指针仅在创建它的线程有效。C/C++创建的线程默认是没有附加到JVM的...

  • 线程池工作流程

    Java线程池主要是用于合理创建线程,减少线程创建销毁频率,最大限度利用CPU性能,JVM根据用户配置先创建一定数...

  • 线程同步(通信)

    线程分类 普通线程:主线程创建的所有子线程都是普通线程守护线程:JVM停止时,抛弃所有守护线程,不执行finall...

  • 线程的5种状态总结

    线程的5种状态 线程可以有如下5种状态:5种状态的转换图如下 New (新创建) 当用new操作符创建一个线程时,...

  • JVM源码分析(二)jvm中的线程

    1. JVM中线程的创建流程 jvm剥离了一套公共的无关平台的线程类:Thread抽象类。Thread类声明在j...

  • jvm的一些笔记

    jvm内存模型 一. 线程私有区域 线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束而创建/销毁(在...

  • Java并发 -- 线程池

    创建线程 创建普通对象,只是在JVM的堆里分配一块内存而已 创建线程,需要调用操作系统内核的API,然后操作系统需...

网友评论

      本文标题:5、JVM可以创建多少线程

      本文链接:https://www.haomeiwen.com/subject/dynurktx.html