Java集合ArrayList、LinkedList、HashMap、HashSet最大容量

发布时间:2023年12月20日

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亿多

在这里插入图片描述

在这里插入图片描述

文章来源:https://blog.csdn.net/weixin_43024834/article/details/135096870
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。