1
cubecube 2023-11-12 11:20:20 +08:00 1
gpt 回答是正确的
和数字大小没关系,int 最大 21 亿 |
2
yfugibr 2023-11-12 11:24:28 +08:00 via Android 1
不止,ArrayList 的空间分配不是要多少就分配多少,而是在容量填满后扩充到之前的大约 1.5 倍(可以去看具体实现),你存 a 个对象,但它分配的空间可能多达 1.5a 个
|
5
rabbbit 2023-11-12 11:27:57 +08:00 1
ArrayList 可以设定初始容量值,避免自动扩容。
int 占 4 字节 嫌多还有 short 2 字节 byte 1 字节 |
6
humpy 2023-11-12 11:32:11 +08:00 4
可以用 [JOL]( https://github.com/openjdk/jol) 工具测一下:
System.out.println(GraphLayout.parseInstance(ints).toFootprint()); --- java.util.ArrayList@5679c6c6d footprint: COUNT AVG SUM DESCRIPTION 1 40016 40016 [Ljava.lang.Object; 10000 16 160000 java.lang.Integer 1 24 24 java.util.ArrayList 10002 200040 (total) 在我的机器上( 64 位 JDK8 ),大约 200040 / 1024 = 195kb |
7
yeqizhang 2023-11-12 11:33:07 +08:00 via Android 1
没啥不相符合的,首先高并发的项目,出现大集合的情况少,其次集群下,单台机的业务并发也不会太高,有高并发的业务都堆机器堆内存去了。
还有就是,只要变成垃圾变的快,jvm 回收了也没啥压力。 |
8
yfugibr 2023-11-12 11:33:51 +08:00 1
@61162833 #4 不是这个意思,ArrayList 底层存储是数组,有一个初始容量(不确定是多少),会在数组被填满时建一个新数组替换旧数组来扩充容量,新数组的容量大约是之前的 1.5 倍(取决于具体实现),直到新数组再次被填满时再次扩容,所以多数情况下都是有空间“浪费”的,但是浪费了多少要看你的存入的容量和 ArrayList 的实现。
当然你也可以直接指定 ArrayList 的容量,这部分就自行搜索吧。 |
9
mazyi 2023-11-12 12:32:58 +08:00 via iPhone
这有啥不经用的,你可以去看看 python 的,和 js 的,让你对编程语言有全新认识
|
10
ruxuan1306 2023-11-12 12:35:52 +08:00
@yfugibr 自动扩容是在 append 时原容量不够才发生的,new 时候给定大小,然后直接用下标设置就不会触发扩容。
|
11
winglight2016 2023-11-12 13:23:28 +08:00
lz 如果觉得内存很容易不够用,可以去看看微机原理这本书,或者了解一下 linux 内核的内存寻址相关内容。
jvm32 位的时候,最大内存只有 1.5G ,的确很容易爆,但是 64 位已经支持到超过硬盘容量了,更大数量的并行计算(如果不需要并行,那限制只是时间问题)已经转变成了分布式计算的问题,而不是高效利用内存——这和 AI 的发展趋势相似,注意力放在了解决通用问题。 |
12
junkun 2023-11-12 14:31:58 +08:00 1
补充一下,如果要省内存可以用 int[]数组,或者自己用数组封装一个 int 类型的线性表。主要是因为 Java 泛型只能支持封装类型的元素,所以占用空间不理想。然而基本类型的数组除了头以外,内部是连续存储的。
|
13
lancelee01 2023-11-13 10:30:58 +08:00
10 万个整数,1.6MB 说实话不大啊。再优化也就是把 List 改成数组,数组本身占用 16 字节,节省 8 字节,整数 int 4 字节,累计 16 + 4 * 100000 ,相当于减少一半
|
15
Aresxue 2023-11-13 11:17:24 +08:00
所以有了 fastutil 这个库。。话说 java 自己的 Valhalla 项目正在做泛型特化以后你就可以用 List<int>了。
|
16
zhouhu 2023-11-13 11:19:37 +08:00
还可以开启指针压缩
|