【问题标题】:OutOfMemoryError for creating native threadsOutOfMemoryError 用于创建本机线程
【发布时间】:2014-11-10 05:45:36
【问题描述】:

我们目前遇到的问题是我们得到如下 OutOfMemoryError

java.lang.OutOfMemoryError: 无法创建新的本地线程

这是一个 spring 集成应用程序

当我进行堆转储时,我注意到在服务器刚刚启动后检查以下“From Space”几乎总是 99% 已满。以下所有统计信息都是在服务器启动后立即进行的。

Attaching to process ID 24167, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.2-b06

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 1887436800 (1800.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 536870912 (512.0MB)
   MaxPermSize      = 1073741824 (1024.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 488112128 (465.5MB)
   used     = 294023920 (280.40306091308594MB)
   free     = 194088208 (185.09693908691406MB)
   60.23696260216669% used
From Space:
   capacity = 44695552 (42.625MB)
   used     = 44676144 (42.60649108886719MB)
   free     = 19408 (0.0185089111328125MB)
   99.95657733458577% used
To Space:
   capacity = 70516736 (67.25MB)
   used     = 0 (0.0MB)
   free     = 70516736 (67.25MB)
   0.0% used
PS Old Generation
   capacity = 715849728 (682.6875MB)
   used     = 16172256 (15.423065185546875MB)
   free     = 699677472 (667.2644348144531MB)
   2.2591691199189783% used
PS Perm Generation
   capacity = 536870912 (512.0MB)
   used     = 74156104 (70.72077178955078MB)
   free     = 462714808 (441.2792282104492MB)
   13.812650740146637% used

我假设这是尝试创建本机线程时出现内存不足错误的最可能原因。

此外,当我通过“top”命令检查进程使用的内存时,它从来都不是 100%,大约是 30% 到 40%。

任何建议

问候, 米琳达

【问题讨论】:

  • top 显示的内存使用量是多少(以 MB 为单位)?您使用的是 32 位 JVM 吗?

标签: java multithreading memory jvm spring-integration


【解决方案1】:

这是 JVM 的一个非常烦人的怪癖,因为“OutOfMemoryError”的措辞让人们感到困惑(他们认为没有足够的堆等)。实际上,这个错误只是意味着:“无法创建新的本地线程”。

之所以不能变化,但如果遇到这种情况,正确的解决办法是找出为什么有这么多线程并限制它们的数量。即使您设法通过调整创建更多线程,您的应用程序的性能也会因线程数过多而受到影响。

您可以使用调试器查看有多少线程处于活动状态。它们可能具有描述性名称,您可以看到它们正在执行的代码。您还可以找出它们是由哪个线程创建的。找出线程的创建位置后,请对其进行修复,使其不会创建太多线程。

【讨论】:

    【解决方案2】:

    每个线程都需要堆栈空间,由 -Xss 设置。奇怪的是,我的

    java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -XX:+LogVMOutput | grep tack
    

    intx ThreadStackSize 为 0,但如果我指定 -Xss2M,则为 2048。无论如何,默认值可能是 64k,所有线程的所有堆栈都必须适合您的最大进程大小,对于 Win32 中的 32 位进程,限制为 1.5GB。

    【讨论】:

      【解决方案3】:

      这个问题有点过时了,但是如果你因为这样的问题来到这里,这里有一点提示来检查 Linux 系统限制。在 Linux 中,限制主要有两个来源: 1. ulimit 2. systemd。 第一个在网络中有很好的记录,有进程限制和文件限制。第二个是自 2016 年以来的新功能,systemd 定义了 DefaultTasksMax 限制。这可能会影响多线程 Java 应用程序和服务。在 /etc/systemd/system.conf 中,可以在系统范围内配置 DefaultTasksMax。不过建议在启动 Java 的 systemd 服务 upstart 文件中调整 TasksMax 设置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多