我的專案使用QTcpSocket和功能setSocketDescriptor()。代碼很正常
QTcpSocket *socket = new QTcpSocket();
socket->setSocketDescriptor(this->m_socketDescriptor);
這種編碼大部分時間都運行良好,直到我在 Windows Server 2016 上運行性能測驗時發生了崩潰。我使用故障轉儲進行除錯,這是日志
0000004f`ad1ff4e0 : ucrtbase!abort 0x4e
00000000`6ed19790 : Qt5Core!qt_logging_to_console 0x15a
000001b7`79015508 : Qt5Core!QMessageLogger::fatal 0x6d
0000004f`ad1ff0f0 : Qt5Core!QEventDispatcherWin32::installMessageHook 0xc0
00000000`00000000 : Qt5Core!QEventDispatcherWin32::createInternalHwnd 0xf3
000001b7`785b0000 : Qt5Core!QEventDispatcherWin32::registerSocketNotifier 0x13e
000001b7`7ad57580 : Qt5Core!QSocketNotifier::QSocketNotifier 0xf9
00000000`00000001 : Qt5Network!QLocalSocket::socketDescriptor 0x4cf7
00000000`00000000 : Qt5Network!QAbstractSocket::setSocketDescriptor 0x256
在 stderr 日志中,我看到了那些日志
CreateWindow() for QEventDispatcherWin32 internal window failed (Not enough storage is available to process this command.)
Qt: INTERNAL ERROR: failed to install GetMessage hook: 8, Not enough storage is available to process this command.
這是函式,代碼在 Qt 代碼庫上停止
void QEventDispatcherWin32::installMessageHook()
{
Q_D(QEventDispatcherWin32);
if (d->getMessageHook)
return;
// setup GetMessage hook needed to drive our posted events
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
if (Q_UNLIKELY(!d->getMessageHook)) {
int errorCode = GetLastError();
qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
errorCode, qPrintable(qt_error_string(errorCode)));
}
}
I did research and the error Not enough storage is available to process this command. maybe the OS (Windows) does not have enough resources to process this function (SetWindowsHookEx) and failed to create a hook, and then Qt fire a fatal signal, finally my app is killed.
I tested this on Windows Server 2019, the app is working fine, no crashes appear.
I just want to know more about the meaning of the error message (stderr) cause I don't really know what is "Not enough storage"? I think it is maybe the limit or bug of the Windows Server 2016? If yes, is there any way to overcome this issue on Windows Server 2016?
uj5u.com熱心網友回復:
當注冊表值設定不正確或最近重置或重新安裝后,配置設定不正確時,Windows 服務器通常會出現錯誤“沒有足夠的存盤空間來處理此命令”。
以下是此問題的經過驗證的程序:
- 單擊開始 > 運行 > regedit 并按 Enter
- 找到這個鍵名 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters
- 找到 IRPStackSize
- 如果此值不存在,請右鍵單擊 Parameters 鍵并單擊 New > Dword Value 并在名稱下鍵入 IRPStackSize。
- 值的名稱必須與我上面的名稱完全相同(大小寫字母的組合)。
- 右鍵單擊 IRPStackSize 并單擊修改
- 選擇十進制輸入大于 15 的值(最大值為十進制 50),然后單擊確定
- 您可以關閉注冊表編輯器并重新啟動計算機。
參考
uj5u.com熱心網友回復:
經過幾天的研究,我終于可以配置 Windows Server 2016 設定(注冊表)以防止崩潰。所以基本上這是作業系統本身的限制,它被稱為desktop heap limitation.
https://docs.microsoft.com/en-us/troubleshoot/windows-server/performance/desktop-heap-limitation-out-of-memory
(有趣的是錯誤資訊是Not enough storage is available to process this command但真正的問題來了desktop heap limitation.)
因此,對于解決方案,請按照此鏈接中的步驟進行操作:https ://docs.microsoft.com/en-us/troubleshoot/system-center/orchestrator/increase-maximum-number-concurrent-policy-instances
我增加了SharedSectionto的第三個引數,2048它解決了這個問題。
總結步驟:
非互動式桌面的桌面堆由以下注冊表值的 SharedSection= 段的第三個引數標識:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SubSystems\Windows
此注冊表值的默認資料如下所示:
%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserServerDllInitialization,3 ServerDll=winsrv:ConServerDllInitialization,2 ProfileControl=Off MaxRequestThreads=16
在 SharedSection= 段的第三個引數中輸入的值應基于以下計算:
(所需并發策略的數量)* 10 =(第三個引數值)
示例:如果希望有 200 個并發策略實體,那么 200 * 10 = 2000,四舍五入到一個不錯的記憶體數會給您 2048 作為第三個引數,從而對注冊表值進行以下更新:
共享部分=1024,3072, 2048
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/443308.html
上一篇:Qt5禁用單擊并按住
