Question

my goal is to write a script that will monitor process memory usage and run % based comparison on it to determine if there is a memory leak in the said process.

I am using the following command to get the momory usage of the process:

tasklist /fi "imagename eq %PROCESS%" /FO csv | findstr K

SAMPLE: "cmd.exe","11640","Console","1","3,160 K"

This gives me a CSV file with last cell being the memory usage. I have two problems that I need help with.

Problem 1) How do I drop all but the last cell so that I can then assign the Kb used to a variable for comparison.

Problem 2) How do I get rid of the comma in the number? That kind of makes using comma as delim hard :/

Is there a better command than tasklist for this? I just need the raw number that the program is using, it can be in KB or MB.

Id love to be able to not have dependencies, but if I have to have dependencies I can include them with the batch.

Also is there any way for findstr to not return the entire line?

Thanks for any help! Ive been trying to get this solved for two days now with not much luck.

Was it helpful?

Solution

@ECHO OFF
SETLOCAL
FOR /f "delims=" %%i IN (memcsv.csv) DO CALL :process %%i 

GOTO :EOF
:process
SET memsize=%~5
SET memsize=%memsize:,=%
ECHO memsize found = %memsize%
GOTO :eof

This should get your output into a variable called memsize.

It uses a file memcsv.csv as input, but you could replace mmcsv.csv with

'tasklist /fi "imagename eq %PROCESS%" /FO csv ^| findstr Mem'

to operate directly on the output of FINDSTR. Your resultant line would thus be

FOR /f "delims=" %%i IN ('tasklist /fi "imagename eq %PROCESS%" /FO csv ^| findstr Mem') DO CALL :process %%i 

which, for ease of legibility could be entered as

FOR /f "delims=" %%i IN (
  'tasklist /fi "imagename eq %PROCESS%" /FO csv ^| findstr Mem'
  ) DO CALL :process %%i 

Note that the line-breaks are specific - before and after the single-quote.

Also that the single-quotes are REQUIRED and that there is a caret (^) before the pipe (|) which tells cmd that the pipe is part of the command to be executed, not part of the FOR command


Edit to add explanation of HOW.

The ouput of the tasklist...|findstr... can be used as input to a for/f as if it was a file. All you need do is to surround the command with SINGLE-QUOTES and ensure that redirectors like | < > are "escaped" by a caret.

FOR /F "reads" the "file" line-by-line, assigning (by default) the first "token" in the line to the "metavariable" (the loop-control variable, %%i in the above case). This behaviour canbe modified by the addition of control-clauses to the FOR/F. You may use `tokens=x,y,z" for instance to assign token number x, number y and number z to %%i, %%j, %%k respectively.

TOKENS are counted from 1 and have a value of the line contents up to a (series of) delimiter(s). By default, delimiters are spaces, commas, semicolons and TABs, so a line

TOKEN_ONE TOKEN_2,TOKEN_THREE;Token_FOUR

when seen by

for /f "tokens=1,3,4" %%i in (filecontainingaboveline) do

would set %%i=TOKEN_ONE %%j=TOKEN_THREE %%k=Token_FOUR

Using "delims=" turns OFF the delimiters and hence the ENTIRE line is assigned to the metavariable.

HENCE, in the above code, the entire line is assigned to %%i and delivered to the subroutine :process.

From :process's point-of-view, it has been given the argument ** "cmd.exe","11640","Console","1","3,160 K"** which it interprets as a sequence of 5 parameters separated by commas - and a comma (or any other separator) WITHIN "quotes" is data, not a separator.

Parameter number 5 is accessed by %5 - and that is "3,160 K" - including the quotes and comma.

The variable is set to the value of the fifth parameter - the tilde (~) means "remove enclosing quotes." Hence memsize acquires a value of 3,160 K The next SET replaces the string after the colon in the nominated variable with the string after the = - replace commas with nothing, and assign the result to the memsize variable.

The goto :eof means 'go to the physical end-of-file.` It is very specific - the colon MUST be present. Reaching end-of-file terminates a subroutine or batch-process.

To remove the last 2 characters of the variable, you could use

SET var=%var:0,~-2%

where var is the variable-name.

SEE

SET /?

from the prompt for documentation.

Also GOTO /? and FOR/? for more details on these commands...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top