Java内存分配限制

发布于 2024-08-14 18:34:44 字数 568 浏览 2 评论 0原文

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

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

StringBuilder a = new StringBuilder(30000);
StringBuilder b = new StringBuilder(30000);

它通常崩溃的点是大约 550 个线程,这会导致略多于 62MB。与程序的其余部分相结合,使用的内存很可能是 64MB,我在网上读到的某个地方是 JVM 内存分配池的默认大小。我不知道这是真的还是假的。

现在,我是否做错了什么,由于设计的原因,我以错误的方式分配内存?或者这是唯一的方法,我应该告诉 JVM 增加其内存池吗?或者完全是别的什么?

另外,请不要告诉我设置较低的容量,我知道这些 StringBuilder 在需要时会自动增加其容量,但我希望有一个解决方案来解决这个问题。

I have a loop that spawns a lot of threads. These threads contains, among other things, 2 (massive) StringBuilder objects. These threads then run and do their thing.

However, I noticed that after a certain amount of threads, I get strange crashes. I know this is because of these StringBuilder, because when I reduce their initial capacity, I can start a lot more threads. Now for these StringBuilders, they are create like this in the constructor of the thread object:

StringBuilder a = new StringBuilder(30000);
StringBuilder b = new StringBuilder(30000);

The point where it generally crashes is around 550 threads, which results in a little bit more than 62MB. Combined with the rest of the program the memory in use is most likely 64MB, which I read online somewhere was the defaulf size of the JVM memory allocation pool. I don't know whether this is true or not.

Now, is there something I am doing wrong, that somehow because of the design, I am allocating memory the wrong way? Or is this the only way and should I tell the JVM to increase its memory pool? Or something else entirely?

Also, please do not tell me to set a lower capacity, I know these StringBuilders automatically increase their capacity when needed, but I would like to have a solution to this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

初见终念 2024-08-21 18:34:44

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

If you are storing a lot of information in a StringBuilder, are you going to reference back to it at some point? If not then just write it to another medium (DB, File etc). The program has a finite amount of resources, it can't hold all of the state of an entire system at once. -Xmx will give you more space for storage in the memory, however it won't make your storage ability infinite.

仅一夜美梦 2024-08-21 18:34:44

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

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

此外,您可以通过将字符串写入文件而不是使用 StringBuilder 将它们保留在内存中来减少内存使用量。

Consider using a ThreadPoolExecutor, and set the pool size to the number of CPUs on your machine. Creating more threads than CPUs is just adding overhead.

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

Also, you can reduce memory usage by writing your strings to files instead of keeping them in-memory with StringBuilders.

白色秋天 2024-08-21 18:34:44

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

Assume 1MB per thread. That's the RAM cost of creating each one, over and above the memory allocated by its process.

千纸鹤带着心事 2024-08-21 18:34:44

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

还可以考虑使用 ThreadPool 或 Executor 来确保只有给定数量的线程同时运行。这样,内存量就可以保持有限,而不会减慢速度(因为您的处理器无论如何都无法同时运行 550 个线程)。

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

As Gregory said, give the jvm, some options like -Xmx.

Also consider using a ThreadPool or Executor to ensure that only a given amount of threads are running simultaneously. That way the amount of memory can be kept limited without slowdown (as your processor is not capable of running 550 threads at the same time anyway).

And when you're using an Executor don't create the StringBuilders in the constructor, but in the run method.

花落人断肠 2024-08-21 18:34:44

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

要减少线程数,您可以使用 ExecutorService,或者简单地使用从队列中读取的几个线程。

我的猜测是,通过一些修改,您可能可以使您的程序根本不需要太多内存。

You can use a FileWriter to output text to a file, then pull it back in with a FileReader. That way you'll only need to store the filename in memory, rather then the entire contents of the string.

To cut down on threads you can use an ExecutorService, or simply use a few threads that read out of a queue.

My guess is that with a little tinkering you can probably get your program down to not needing much memory at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文