Java内存分配限制

Java内存分配限制,java,limit,heap-memory,Java,Limit,Heap Memory,我有一个产生很多线程的循环。除其他外,这些线程包含2个(大量)StringBuilder对象。然后这些线程运行并执行它们的操作 然而,我注意到,经过一定数量的线程之后,我会出现奇怪的崩溃。我知道这是因为这些StringBuilder,因为当我减少它们的初始容量时,我可以启动更多的线程。现在,对于这些StringBuilder,它们是在thread对象的构造函数中创建的: StringBuilder a=新StringBuilder(30000) StringBuilder b=新StringBu

我有一个产生很多线程的循环。除其他外,这些线程包含2个(大量)StringBuilder对象。然后这些线程运行并执行它们的操作

然而,我注意到,经过一定数量的线程之后,我会出现奇怪的崩溃。我知道这是因为这些StringBuilder,因为当我减少它们的初始容量时,我可以启动更多的线程。现在,对于这些StringBuilder,它们是在thread对象的构造函数中创建的:

StringBuilder a=新StringBuilder(30000)
StringBuilder b=新StringBuilder(30000)

它通常崩溃的点大约是550个线程,这会导致62MB多一点。再加上程序的其余部分,使用的内存很可能是64MB,我在网上看到的是JVM内存分配池的defaulf大小。我不知道这是不是真的

现在,是否有什么我做错了,不知怎么的,因为设计,我分配内存的方式不对?或者这是唯一的方法,我应该告诉JVM增加它的内存池吗?或者完全是别的什么


另外,请不要告诉我设置较低的容量,我知道这些StringBuilder会在需要时自动增加其容量,但我想找到解决此问题的方法。

使用
-Xmx
JVM选项来增加Java最大堆大小


如果您在StringBuilder中存储了大量信息,您是否打算在某个时候引用它?如果没有,则只需将其写入另一个介质(数据库、文件等)。程序有有限的资源,它不能同时保存整个系统的所有状态-Xmx将为内存中的存储提供更多的空间,但它不会使您的存储能力无限大。

假设每个线程有1MB。这是创建每个进程所需的RAM成本,超出了进程分配的内存。

正如Gregory所说,给jvm一些选项,比如-Xmx

还考虑使用线程池或执行器来确保只有给定数量的线程同时运行。这样,内存量就可以在不降低速度的情况下保持有限(因为您的处理器无论如何都不能同时运行550个线程)


当您使用执行器时,不要在构造函数中创建StringBuilder,而是在run方法中创建StringBuilder。

考虑使用
ThreadPoolExecutor
,并将池大小设置为您机器上的CPU数量。创建比CPU更多的线程只会增加开销

ExecutorService service = Executors.newFixedThreadPool(cpuCount))
另外,您可以通过将字符串写入文件而不是使用
StringBuilder
s将其保存在内存中来减少内存使用。

您可以使用将文本输出到文件,然后使用文件读取器将其拉回。这样,您只需要将文件名存储在内存中,而不需要存储字符串的全部内容

要减少线程数量,可以使用ExecutorService,或者只使用几个从队列中读取的线程


我的猜测是,只要稍加修改,您就可以使程序完全不需要太多内存

不,我甚至不想知道为什么那500多个线程会分配那些怪物StringBuilder:p首先想到的是为什么会产生这么多线程?你也可以尝试不指定初始容量。然后,StringBuilder将从小做起,只有在需要时才会成长。这不依赖于平台吗?我可能错了,但我认为它是错的(可以使用
-XX:ThreadStackSize=size
选项进行调整,请参见)。我引用的是一个粗略的经验法则,而不是你刚才所说的精确值。谢谢你的引用。