首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何增加windows服务可以派生的子进程的最大数量--桌面堆限制

如何增加windows服务可以派生的子进程的最大数量--桌面堆限制
EN

Stack Overflow用户
提问于 2013-07-04 22:06:02
回答 2查看 23.7K关注 0票数 25

问:我有一个windows服务,它派生了很多子进程。似乎有一些限制,大约在100左右,进程不能启动。CreateProcess()调用返回一个pid,但随后该进程就无法实现。如果我将我们的服务器作为控制台应用程序运行,这个限制就不存在了。而且,如果我设置了DETACHED_PROCESS标志,这个限制会增加一倍以上。但是,如果我设置了DETACHED_PROCESS并调用CreateProcesssWithLogonW(),我就会失败。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-04 22:06:02

这是一个“桌面堆”问题。在这里可以找到一个非常好的讨论:

Desktop Heap OverviewDesktop Heap, Part 2

请注意,这只适用于作为服务运行的程序,因为服务的默认桌面堆大小远远小于应用程序的默认桌面堆大小。

在我们的例子中,我们能够在资源耗尽之前启动大约100个子进程,而不需要更改。随着这一变化,这个数字可以显著增加。

这是我们在知识库中给我们的最终用户的答案:

警告:这会影响所有服务的桌面堆!不要使其超出必要的大小,否则会使系统消耗更多的资源,并且可能会遇到总可用桌面堆大小的问题。

如果您发现即使在非常大的RAM服务器上打开的项目总数也不能超过100个,则可能会遇到Windows“桌面堆大小”的限制。

问题是windows下的服务会话(服务运行的地方)用于创建窗口的“桌面堆”空间较少。

简短的版本是:

与交互式会话相比,

  • 服务获得的桌面堆更小。
  • 桌面堆大小限制windows
  • 每个子服务器创建一个或多个“窗口”的数量,即使我们看不到它们。

解决方案:

  1. 在进行任何更改之前备份注册表!
  2. 以管理员身份运行regedit.exe
  3. 编辑注册表值:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows

  • You将看到一个类似如下的字符串:

MaxRequestThreads=16 %SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:ConServerDllInitialization,2 ServerDll=sxssrv,4 ProfileControl=Off ProfileControl=Off

关键位是:

SharedSection=1024,20480,768

第二个数字(20480)是交互式会话的大小。第三个数字(768)是非交互式(服务)会话的大小。注意第三个数字是如何比第二个数字小26倍的。在实验中,我们发现将其更改为:

SharedSection=1024,20480,2048

将项目限制从106增加到270,几乎可以完美地随堆大小进行扩展。选择一个反映您希望系统上的所有用户同时打开的最大项目数的值。请不要将此值设置为大于必要的值,并且不要大于8192,因为系统中的每个服务都将消耗更多的宝贵资源。

您需要重新启动才能使这些新设置生效。

票数 38
EN

Stack Overflow用户

发布于 2016-12-08 05:52:21

我们有许多远程桌面服务器,我们需要在上面测试它,所以我们写了一个powershell脚本来查询我们的RD服务器的AD,然后应用这个注册表更改。尽情享受

代码语言:javascript
运行
复制
   $newValue = "%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,2048 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16"
$origValue = "%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,20480,768 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=sxssrv,4 ProfileControl=Off MaxRequestThreads=16"

if ($update) {
    Clear-Variable update
}

$updateConfirm= [System.Windows.Forms.MessageBox]::Show("Update Desktop Heap Limitation to 2048?" , "Status" , 4) 
if ($updateConfirm -eq "YES" ) {
    $update = $true
} else { 
    $revertConfirm= [System.Windows.Forms.MessageBox]::Show("Revert Desktop Heap Limitation to 768?" , "Status" , 4) 
    if ($revertConfirm -eq "YES" ) {
        $update = $false
    } 
}

if (($updateConfirm -ne "YES") -and ($revertConfirm -ne "YES")) {
    Write-Host "User did not specify whether to update or revert Desktop Heap Limitation. Exiting Setup."
    Read-Host "Press Enter to exit."
    break
}

#Import Active Directory PowerShell module
if (Test-Path C:\Users\${env:USERNAME}\Documents\WindowsPowerShell\Modules\ActiveDirectory\ActiveDirectory.psm1) {
    Import-Module ActiveDirectory -prefix AD
} else {
    $s = New-PSSession -computerName DC01WDC01
    Invoke-command { import-module ActiveDirectory } -session $s
    Export-PSSession -session $s -commandname *-AD* -outputmodule ActiveDirectory -allowclobber
    Import-Module ActiveDirectory -prefix AD
    Remove-PSSession -session $s
}

$servers =  Get-ADADComputer -Filter {(Name -Like "RDS*")}  | Select -Expand Name

foreach ($server in $servers) {
    Write-Host "Working on $server" -ForegroundColor Magenta
    if(!(Test-Connection -ComputerName $server -Count 1 -quiet)) {
        Write-Warning "$server : Offline"
        Continue
    }

    if ($update -eq $true) {
        Invoke-Command -ComputerName $server -ArgumentList $newValue -ScriptBlock {
            Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems" -Name "Windows" -Value $args[0]
            $result = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems" | SELECT Windows
            if ($result.Windows -like "*SharedSection=1024,20480,2048*") {
                Write-Host "Successfully reverted Desktop Heap Limit to 2048" -ForegroundColor Green
            } else {
                Write-Warning "Update to registry value unsuccessful on $env:ComputerName" 
            }              
        }
    } elseif ($update -eq $false) {
        Invoke-Command -ComputerName $server -ArgumentList $origValue -ScriptBlock {
            Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems" -Name "Windows" -Value $args[0]
            $result = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems" | SELECT Windows    
            if ($result.Windows -like "*SharedSection=1024,20480,768*") {
                Write-Host "Successfully reverted Desktop Heap Limit to 768" -ForegroundColor Green
            } else {
                Write-Warning "Update to registry value unsuccessful on $env:ComputerName" 
            }       
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17472389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档