Java集合ArrayList、LinkedList、HashMap、HashSet最大容量
文章目录
1. 堆栈都溢出了,集合再大又有什么用
首先要保证不能栈溢出(StackOverflowError)、内存溢出OutOfMemoryError
默认最大堆大小1GB,默认最大栈大小1MB(只是一个虚拟机栈,就是一个线程,就是一次http请求)
- 32位的JVM上,物理内存小于192MB时,为物理内存的一半;物理内存大于192MB且小于4GB时,为物理内存的四分之一;大于等于4GB时,都为1GB
- 64位的JVM上,物理内存小于192MB时,为物理内存的一半;物理内存大192MB且小于128GB时,为物理内存的四分之一;大于等于128GB时,都为32GB
比如4G内存,默认最大堆内存是1G
可以通过JVM启动参数控制:
-Xms设置堆的最小空间大小。
-Xmx设置堆的最大空间大小。
-XX:NewSize设置新生代最小空间大小。
-XX:MaxNewSize设置新生代最大空间大小。
-XX:PermSize设置永久代最小空间大小。
-XX:MaxPermSize设置永久代最大空间大小。
-Xss设置每个线程的堆栈大小。
1.1 StackOverflowError触发场景
叽里呱啦
导致StackOverflowError的原因
如上图,一个线程开启一个虚拟机栈,虚拟机栈的大小有限制,默认是1024kb=1mb,也就是说一个线程的最大栈大小是1mb,
而,方法数对应着栈帧数,栈帧占的内存越多,能达到的最大栈深度也就越小。
java虚拟机栈是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是java方法执行的线程内存模型,每个方法被执行的时候,java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法返回地址等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程。
-
每个线程都有自己的栈,栈中的数据都是以栈帧(Stack Frame)的格式存在。
-
在这个线程上正在执行的每个方法都各自对应一个栈帧(Stack Frame)。
-
栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各种数据信息。
-
设置栈内存大小
我们可以使用参数-Xss选项来设置线程的最大栈空间,栈的大小直接决定了函数调用的最大可达深度。如果程序使用了很深的递归函数,而栈内存又非常小,此时很有可能发生栈溢出(java.lang.StackOverflowError)的情况。
每一个线程都有独立的栈空间。如果想尽量多跑一些线程的话,就尽量将栈内存缩小,而不是增大。
设置单个线程栈大小,一般默认1024kb。单个线程栈大小跟操作系统和JDK版本都有关系 -Xss = -XX:ThreadStackSize。
栈溢出主要在两点:
- 一是栈深度的限制,比如不加约束的递归就会造成栈溢出,一个方法就是一个栈帧,栈由栈帧组成,也就是说方法越多,栈的深度越深,那么栈的最大深度到底是多少呢,这个又由栈帧的大小影响,栈帧越大,栈的最大深度越小。
- 二是栈的内存大小不能超过最大栈大小,默认是1mb,注意这里是单个线程的限制
总结:方法小,局部变量小,栈帧就小,栈最大深度就更深,栈帧出栈也就更快,对象的引用更早消失,对象更早可能被回收。
1.2 OutOfMemoryError触发场景
- 静态集合:类在集合就一直在,导致集合中的对象一直被引用,而不会像方法中的局部变量一样,随着方法运行完,栈帧弹出,局部变量消失,对象失去引用可以对gc回收,静态集合对应的对象无法回收容易引发内存溢出
2. tomcat都处理不过来了集合再大又有什么用
2.1 tomcat连接配置
SpringBoot开发最大的好处是简化配置,内置了Tomcat, 在SpringBoot2.0.x版本中内置Tomcat版本是8.5.x,SpringBoot内置Tomcat的默认设置中,Tomcat的等待队列长度默认是100,Tomcat的最小工作线程数默认分配10,Tomcat的最大线程数是200,最大连接数是10000,至于最大并发量和最大连接数,常常理解成最大并发量就是最大连接数,实际上是有些牵强的,最大连接数并不一定就是最大并发量。
- 默认最大连接数maxConnections = 10000
- 默认队列长度acceptCount = 100
- 默认最大工作线程数maxThreads = 200
- 默认最小工作线程数 minSpareThreads = 10
2.2 tomcat报文大小配置
在application.yml中,可以使用以下配置来设置响应报文最大值(据说默认是2mb):
server:
tomcat:
max-http-header-size: 4048576
spring:
servlet:
multipart:
enabled: true
max-file-size: 1000MB
max-request-size: 1000MB
springboot默认请求最大值可以通过配置文件进行设置。在springboot应用中,tomcat的默认配置文件是spring-configuration-metadata.json,它位于spring-boot-autoconfigure-版本号.jar这个包下面。在该配置文件中,可以找到关于tomcat的默认配置参数。
其中,最大连接数的配置参数为server.tomcat.max-connections,默认值为10000。该参数表示在任何给定时间,tomcat服务器可以接受和处理的最大连接数。
另外,请求正文的大小的默认最大值为2MB,可以通过配置参数server.tomcat.max-http-form-post-size进行设置。默认值为2MB。如果要取消对请求正文大小的限制,可以将该值设置为-1。
所以,springboot默认请求最大值的配置参数如下:
最大连接数:server.tomcat.max-connections,默认值为10000。
请求正文大小:server.tomcat.max-http-form-post-size,默认值为2MB。
3. 终于到正文了,集合到底size最大是多少
ArrayList:底层是数组,最大size是int的最大值,21亿多
LinkedList:底层是双向链表,最大可以无限大
HashMap、HashSet:HashSet的就是HashMap实现的,底层是数组、单向链表或红黑树,这俩最大size一样,也是int的最大值,21亿多