2015-03-30 2 views
1

Я боролся с этим в течение недели и исчерпал все методы и варианты, которые я нашел в Интернете. Я надеюсь, что кто-то здесь сможет мне помочь.Расход памяти памяти Powershell Issue

Я использую powershell для запуска 8 заданий, каждое задание FFmpeg для передачи 7-минутного файла на удаленный RTMP-сервер. Это извлекается из файла на диске, и каждое задание использует другой файл. Команда находится в цикле do while, так что она постоянно перегорает.

Это вызывает оболочку, из которой я запускал задания, чтобы накопить огромное количество памяти, потребляя все, что может. В течение 24 часов он потреблял 30 из 32 ГБ моего сервера.

Вот мой код запуска, любая помощь будет оценена по достоинству.

start-job -Name v6 -scriptblock { 
do { $d = $true; $f = Invoke-Expression -Command "ffmpeg -re -i `"C:\Shares\Matthew\180p_3000k.mp4`" -vcodec copy -acodec copy -f flv -y rtmp://<ip>/<appName>/<streamName>"; $f = $null } 
while ($d = $true) 

}

Я пытался получить работу и через канал, из-нуля, я попытался установить $ е до $ нуля перед запуском делать во время цикла, и некоторые другие вещи, которые я найти онлайн, но безрезультатно. Спасибо всем за ваше время!

+0

делать {} при этом ($ D = $ True) –

+1

** делать {} в то время ($ d = $ истина) ** является бесконечная петля. Ваше выражение будет вызываться снова и снова ... Если вы хотите проверить условие, выполняйте ** while ($ d -eq $ true) ** Затем снова «do {$ d = $ true; } while ($ d -eq $ true) 'также является бесконечным циклом, если вы не установите где-либо $ d в $ false. Что-то не так с вашей логикой. Можете ли вы попытаться ввести логику в слова в свой вопрос? Постоянно переигрывать? Или повторная потоковая передача, когда заканчивается один поток? –

+0

О, мужик, глупая ошибка, которую я сделал снова. Я поменяю ее на $ d -eq $ true, но она должна быть бесконечным looo. Когда 7-минутный клип заканчивается, он должен снова повторить его. Может быть, я не должен делать бесконечный цикл и ждать завершения задания и переделать работу? –

ответ

3

Лучше поздно, чем никогда. У меня была такая же проблема с огромным потреблением памяти при запуске ffmpeg в работе Powershell. Суть проблемы заключается в том, что работа Powershell будет хранить любой/весь вывод в памяти, и ffmpeg с удовольствием регистрирует вывод как на стандартный выход, так и на стандарт ошибка потоков.

Моим решением было добавить параметр «-lvelvel quiet» в ffmpeg. В качестве альтернативы вы можете перенаправить как стандартные, так и потоки ошибок в null (этого недостаточно, чтобы перенаправить только стандартный поток). Более подробную информацию о том, как перенаправить стандартные потоки, относятся к этому вопросу: Redirection of standard and error output appending to the same log-file

+0

Спасибо, что было полезно! Я собираюсь попробовать это. Работа над мной в течение некоторого времени заключалась в том, чтобы набивать команды ffmpeg в пакетные файлы. Если бы мне нужно было быть динамичным, я бы написал команды в виде пакетного файла и запустил их из сценария. Казалось, что память не ползала. Это еще раз доказывает вашу точку зрения - я считаю, что то, что я делал, вызывало определенную степень разделения, чтобы предотвратить остановку stdout или stderr в пространстве имен powershell. –

2

Существует много способов вызвать сценарий PowerShell или выражение.

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

$Throttle = 10 # Maximum jobs that can run simultaneously in a runpool 
$maxjobs = 8 # Maximum jobs that will run simultaneously 
[System.Collections.ArrayList]$jobs = @() 
$script:currentjobs = 0 
$jobindex = 0 
$jobaction = "ffmpeg -re -i `"C:\Shares\Matthew\180p_3000k.mp4`" -vcodec copy -acodec copy -f flv -y rtmp://<ip>/<appName>/<streamName>" 

$sessionstate = [system.management.automation.runspaces.initialsessionstate]::CreateDefault() 
$runspace = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host) 
$runspace.Open() 


function QueueJob{ 
    param($jobindex) 
    $job = "" | Select-Object JobID,Script,Errors,PS,Runspace,Handle 
    $job.JobID = $jobindex 
    $job.Script = $jobaction 
    $job.PS = [System.Management.Automation.PowerShell]::create() 
    $job.PS.RunspacePool = $runspace 
    [void]$job.PS.AddScript($job.Script) 
    $job.Runspace = $job.PS.BeginInvoke() 
    $job.Handle = $job.Runspace.AsyncWaitHandle 
    Write-Host "----------------- Starting Job: $("{0:D4}" -f $job.JobID) --------------------" -ForegroundColor Blue 
    $jobs.add($job) 
    $script:currentjobs++ 
} 

Function ServiceJobs{ 
    foreach($job in $Jobs){ 
     If ($job.Runspace.isCompleted) { 
      $result = $job.PS.EndInvoke($job.Runspace) 
      $job.PS.dispose() 
      $job.Runspace = $null 
      $job.PS = $null 
      $script:currentjobs-- 
      Write-Host "----------------- Job Completed: $("{0:D4}" -f $job.JobID) --------------------" -ForegroundColor Yellow 
      Write-Host $result 
      $Jobs.Remove($job) 
      return 
     } 
    } 
} 

while ($true) { 
    While ($script:currentjobs -le $maxjobs){ 
     QueueJob $jobindex 
     $jobindex++ 
    } 
    ServiceJobs 
    Start-Sleep 1 
} 

$runspace.Close() 
[gc]::Collect() 

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

+0

Я только что увидел это - спасибо - я попытаюсь выяснить, как это использовать.Мне нравится эта идея, и я думаю, что мое фактическое решение этой проблемы было вызвано тем, что было косвенно запущено ffmpeg в новом пространстве имен, запустив его, вызвав динамический пакетный файл. –

Смежные вопросы