Как заставить.NET обработать исчерпанный память, не исчерпывая всю системную память

Мы используем заголовки, и у нас есть Laravel 5.1, но мы делаем что-то немного другое, когда мы на короткое время кэшируем наши файлы и создаем динамические изображения графиков с помощью плагина c3. В конце моего поста я покажу, как мы используем эти заголовки с кешем.

Убедитесь, что вы добавили маршрут:

Route::get('/files/projects/{file}', 'DownloadController@index');

См. Этот пост SO

$file= public_path(). $name;

Laravel < 5

$headers = array(
          'Content-Type: image/jpeg',
        );

  return Response::download($file, $name.'jpg', $headers);

Laravel> = 5

  return response()->download($file, $name."jpg");

ПРИМЕЧАНИЕ: Вот реализация кэшированного изображения ... ( обратите внимание на код base64_en для двоичных файлов, т. е.: .png .jpg)

  $responseHeaders = array(
            'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
            'Content-Type' => 'image/png',
            'Content-Disposition' => 'attachment; filename=' . $outputFileName . '.png',
            'Expires' => '0',
            'Pragma' => 'public'
        );


$url = action('DownloadController@standAlone', ['cat' => $category]);

        // Values cached for 1 minute... ???
        if (Cache::has($url)){
            return Response(base64_decode(Cache::get($url)))->withHeaders($responseHeaders);
        } else {
            $maxWidth = 2560;
            $maxHeight = 854;
            $minWidth = 780;
            $minHeight = 260;

            if ($height > $maxHeight) {
                $height = $maxHeight;
            }

            if ($height < $minHeight) {
                $height = $minHeight;
            }

            if ($width > $maxWidth) {
                $width = $maxWidth;
            }

            if ($width < $minWidth) {
                $width = $minWidth;
            }

            $command = app_path('bin/phantomjs');
            $command .= ' ' . app_path('bin/maketrendpng.js');
            $command .= ' ' . escapeshellarg($url);
            $command .= ' /dev/stdout';
            $command .= ' ' . escapeshellarg($height);
            $command .= ' ' . escapeshellarg($width);
            $command .= ' ' . request()->server->get('SERVER_NAME');
            $command .= ' ' . escapeshellarg(

Мы используем заголовки, и у нас есть Laravel 5.1, но мы делаем что-то немного другое, когда мы на короткое время кэшируем наши файлы и создаем динамические изображения графиков с помощью плагина c3. В конце моего поста я покажу, как мы используем эти заголовки с кешем.

Убедитесь, что вы добавили маршрут:

[110]

См. Этот пост SO

[111]

Laravel < 5

[112]

Laravel> = 5

[113]

ПРИМЕЧАНИЕ: Вот реализация кэшированного изображения ... ( обратите внимание на код base64_en для двоичных файлов, т. е.: .png .jpg)

[114]COOKIE[env('SESSION_COOKIE', 'laravel_session')]); $command .= ' ' . escapeshellarg(env('SESSION_COOKIE', 'laravel_session')); $handle = popen($command, 'r'); $contents = ''; while (!feof($handle)) { $contents .= fread($handle, 8192); } pclose($handle); Cache::put($url, base64_encode($contents), 1); return Response($contents)->withHeaders($responseHeaders);

6
задан bendewey 7 May 2009 в 20:28
поделиться

4 ответа

Лучше всего издеваться. На самом деле повышение ООМ по определению не является модульным тестом. Имея дело с памятью, вы имеете дело с нагрузочным тестированием. Если вы прочтете ссылки внизу этого письма, то обнаружите, что настоящие OOM крайне сложно воспроизвести и отладить в лучшем случае. Придуманное исключение OOM не является истинной причиной исключения, и, следовательно, не более интересно, чем макет для тестирования.

Придерживайтесь модульного теста, используя макет для проверки. Если вы по-прежнему получаете OOM, выделите больше памяти на вашем сервере и сделайте процесс перезапускать / перезапускать чаще.

Вот несколько интересных чтений об исключениях OutMemory, которые я собрал в последний раз, когда сражался с ними. Описание: OOM возникают, когда система не может выделить запрошенную вами сумму, что не означает, что у вас недостаточно памяти.

1
ответ дан 17 December 2019 в 18:19
поделиться

Довольно легко вызвать исключения нехватки памяти в процессе.

Просто создайте цикл, который выделяет память в блоках, которые достаточно малы, чтобы не находиться в куче больших объектов (но не слишком много, что у вас вызывает исключение), а затем вы можете попытаться открыть файл меньшего размера, и это приведет к привести к тому, что открытие файла не сможет выделить достаточно непрерывной памяти, и вы получите исключение OOM при открытии файла без необходимости в огромном файле. Примерно так ...

List<byte[]> items = new List<byte[]>();
for (int i = 0; i < 10000; i++)
{
     byte[] c = new byte[160000];
     items.Add(c);
}

byte[] next = new byte[1000000000];

Если вы запустите приведенный выше код как есть, вы получите исключение OOM в последней строке. Но если вы сначала закомментируете цикл, он будет выполняться без ошибок. Вам, вероятно, придется немного подправить цикл, чтобы он каждый раз приводил к сбою при открытии файла, но вы можете это сделать. Просто запустите цикл перед вызовом, чтобы открыть файл в вашем тесте, и вы израсходуете большой кусок памяти, и ваше открытие должно завершиться ошибкой.

Кроме того, вы можете захотеть установить переключатель / 3GB, если он вариант для вас. Это не всегда правильный ответ, и с ним связаны недостатки, но он изменяет разделение виртуальной памяти с 2 ГБ / 2 ГБ на 1 ГБ / 3 ГБ, позволяя вашему процессу получить доступ к большему количеству виртуального адресного пространства. Это даст вам немного больше пространства для открываемых файлов. Опять же, вам следует прочитать о недостатках этого, прежде чем использовать это как решение, и убедиться, что оно того стоит, если оно поможет вашей ситуации.

Здесь показано, как включить его на сервере

вы можете захотеть установить переключатель / 3GB, если это вариант для вас. Это не всегда правильный ответ, и с ним связаны недостатки, но он изменяет разделение виртуальной памяти с 2 ГБ / 2 ГБ на 1 ГБ / 3 ГБ, позволяя вашему процессу получить доступ к большему количеству виртуального адресного пространства. Это даст вам немного больше пространства для открываемых файлов. Опять же, вам следует прочитать о недостатках этого, прежде чем использовать это как решение, и убедиться, что оно того стоит, если оно поможет вашей ситуации.

Здесь показано, как включить его на сервере

возможно, вы захотите установить переключатель / 3GB, если это вам подходит. Это не всегда правильный ответ, и с ним связаны недостатки, но он изменяет разделение виртуальной памяти с 2 ГБ / 2 ГБ на 1 ГБ / 3 ГБ, позволяя вашему процессу получить доступ к большему количеству виртуального адресного пространства. Это даст вам немного больше пространства для открывания файлов. Опять же, вы должны прочитать о недостатках этого, прежде чем использовать это в качестве решения, и убедиться, что оно того стоит, если оно поможет вашей ситуации.

Здесь показано, как включить его на сервере

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

Здесь показано, как включить его на сервере

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

Здесь показано, как включить его на сервере

0
ответ дан 17 December 2019 в 18:19
поделиться

Разве вы не можете использовать фреймворк для выделения памяти и заставить его выбросить OutOfMemoryException в качестве одного из тестов?

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

Пример: У меня был случай на предыдущей работе, когда мы отображали 3D-модели заводов в реальном времени. Модели стали настолько большими, что, когда мы пытались загрузить текстуры, у нас заканчивались сбои памяти. Нам удалось сохранить работоспособность приложения и визуализацию, убедившись, что код справляется с нулевыми указателями, хотя остальная часть кода считала, что там должна быть информация о текстуре.

2
ответ дан 17 December 2019 в 18:19
поделиться

I don't quite understand what you're getting at here. Let's suppose that somehow you created an artificially small "test environment" that couldn't allocate as-big chunks of memory, so it threw OutOfMemoryExceptions on smaller files. What have you gained? The unit test was supposed to test whether you can handle bigger files on a real system, right?

The important thing is presumably that you can handle files "as big as they need to be" on whatever system they're going to be running on, and there's no real way to unit test that outside of trying out that file on that system.

(A smaller, less important thing might be whether you handle OutOfMemoryExceptions gracefully, but you don't need to actually run out of memory to test that; just make your method throw an exception once in a while and observe that it does the right thing.)

0
ответ дан 17 December 2019 в 18:19
поделиться
Другие вопросы по тегам:

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