代码之家  ›  专栏  ›  技术社区  ›  Marc

Java内存分配限制

  •  0
  • Marc  · 技术社区  · 15 年前

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

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

    StringBuilder A=新的StringBuilder(30000);
    StringBuilder B=新的StringBuilder(30000);

    它通常崩溃的地方是大约550个线程,这会导致略多于62MB的内存。与程序的其余部分结合起来,使用中的内存很可能是64MB,我在某个地方在线阅读的是JVM内存分配池的defaulf大小。我不知道这是不是真的。

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

    另外,请不要告诉我设置一个较低的容量,我知道这些架线建设者在需要时会自动增加他们的容量,但我想有一个解决这个问题的方法。

    6 回复  |  直到 15 年前
        2
  •  3
  •   monksy    15 年前

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

        3
  •  2
  •   Sam Barnum    15 年前

    考虑使用 ThreadPoolExecutor ,并将池大小设置为计算机上的CPU数。创建比CPU多的线程只是增加了开销。

    ExecutorService service = Executors.newFixedThreadPool(cpuCount))
    

    此外,还可以通过将字符串写入文件而不是将其保存在内存中来减少内存使用量。 StringBuilder S.

        4
  •  1
  •   duffymo    15 年前

    假设每个线程为1MB。这就是在进程分配的内存之上创建每个内存的RAM成本。

        5
  •  1
  •   extraneon    15 年前

    正如格雷戈里所说,给JVM一些选项,比如-xmx。

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

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

        6
  •  0
  •   Chad Okere    15 年前

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

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

    我的猜测是,只要稍加修改,你的程序可能就不需要太多内存了。