Критические Разделы, пропускающие память на Vista/Win2008?

Я протестировал эту конфигурацию с течением времени, мне пришлось проследить с помощью tcpdump и даже проверить мои журналы, потому что я подозревал, что проблема связана с сетью. Я узнал, что на самом деле клиент CASH сбрасывал соединение до того, как TLS-рукопожатие завершается.

2019/03/02 06:54:58 [error] 27569#27569: *62 peer closed connection in SSL handshake (104: Connection reset by peer) while SSL handshaking to upstream, client: xx.xx.xx.xx, server: 1270.0.0.1, request: "GET / HTTP/1.1", upstream: "https://xx.xx.xx.xx:1000/", host: "xx.xx.xx.xx:80"

Спасибо всем, что просмотрели, но сценарий правильный.

5
задан Community 23 May 2017 в 12:01
поделиться

3 ответа

Microsoft действительно изменила способ работы InitializeCriticalSection в Vista, Windows Server 2008 и, возможно, также в Windows 7.
Они добавили «функцию» для сохранения некоторой памяти, используемой для отладочной информации, когда вы выделяете связку CS. Чем больше вы выделяете, тем больше памяти сохраняется. Он может быть асимптотическим и в конечном итоге выровняться (не полностью купленный для этого).
Чтобы избежать этой «возможности», вы должны использовать новый API InitalizeCriticalSectionEx и передать флаг CRITICAL_SECTION_NO_DEBUG_INFO .
Преимущество этого заключается в том, что это может быть быстрее, так как очень часто будет использоваться только spincount, не дожидаясь фактического ожидания.
Недостатки состоят в том, что ваши старые приложения могут быть несовместимы , вам нужно изменить код, и теперь он зависит от платформы (вам нужно проверить версию, чтобы определить, какое из них использовать). Кроме того, вы теряете возможность отладки, если вам это нужно.

Тестовый комплект для замораживания Windows Server 2008:
- создайте этот пример C ++ как CSTest.exe

#include "stdafx.h" 
#include "windows.h" 
#include <iostream> 

using namespace std; 

void TestCriticalSections() 
{ 
  const unsigned int CS_MAX = 5000000; 
  CRITICAL_SECTION* csArray = new CRITICAL_SECTION[CS_MAX];  

  for (unsigned int i = 0; i < CS_MAX; ++i)  
    InitializeCriticalSection(&csArray[i]);  

  for (unsigned int i = 0; i < CS_MAX; ++i)  
    EnterCriticalSection(&csArray[i]);  

  for (unsigned int i = 0; i < CS_MAX; ++i)  
    LeaveCriticalSection(&csArray[i]);  

  for (unsigned int i = 0; i < CS_MAX; ++i)  
    DeleteCriticalSection(&csArray[i]); 

  delete [] csArray; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
  TestCriticalSections(); 

  cout << "just hanging around..."; 
  cin.get(); 

  return 0; 
}

-... Запустите этот командный файл (требуется sleep.exe из SDK сервера)

@rem you may adapt the sleep delay depending on speed and # of CPUs 
@rem sleep 2 on a duo-core 4GB. sleep 1 on a 4CPU 8GB. 

@for /L %%i in (1,1,300) do @echo %%i & @start /min CSTest.exe & @sleep 1 
@echo still alive? 
@pause 
@taskkill /im cstest.* /f

-... и просмотрите сервер Win2008 с 8 ГБ и зависанием четырехъядерных процессоров до достижения 300 запущенных экземпляров.
-... повторите на сервере Windows 2003 и вы увидите, как он справляется с этим как с шармом.

7
ответ дан 13 December 2019 в 22:16
поделиться

You're seeing something else.

I just built & ran this test code. Every memory usage stat is constant - private bytes, working set, commit, and so on.

int _tmain(int argc, _TCHAR* argv[])
{
    while (true)
    {
        CRITICAL_SECTION* cs = new CRITICAL_SECTION[1000000];
        for (int i = 0; i < 1000000; i++) InitializeCriticalSection(&cs[i]);
        for (int i = 0; i < 1000000; i++) DeleteCriticalSection(&cs[i]);
        delete [] cs;
    }

    return 0;
}
1
ответ дан 13 December 2019 в 22:16
поделиться

Ваш тест, скорее всего, не является типичным признаком проблемы. Критические секции считаются «облегченными мьютексами», потому что настоящий мьютекс ядра не создается при инициализации критической секции. Это означает, что ваши критические разделы 10M просто структуры с несколькими простыми членами. Однако, когда два потока обращаются к CS одновременно, для их синхронизации действительно создается мьютекс - и это другая история.

Я предполагаю, что в вашем реальном приложении потоки сталкиваются, в отличие от вашего тестового приложения. Теперь, если вы действительно рассматриваете критические секции как легкие мьютексы и создаете их много, ваше приложение может выделять большое количество реальных мьютексов ядра, которые намного тяжелее, чем объект легких критических секций. И поскольку мьютексы являются объектами ядра, создание их чрезмерного числа может действительно повредить ОС.

Если это действительно так, вам следует сократить использование критических секций, где вы ожидаете много коллизий. Это не имеет ничего общего с версией для Windows, так что я могу ошибаться, но это все же нужно учитывать. Попробуйте отслеживать количество дескрипторов ОС и посмотрите, как работает ваше приложение.

2
ответ дан 13 December 2019 в 22:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: