whos - I can't capture the output

15 views (last 30 days)
dormant
dormant on 19 Jan 2024
Commented: Star Strider on 22 Jan 2024
I need to debug a script that has memory issues. So I decided to use whos to print out the largest variables while it is running.
The option to store the output in a cell array doesn't seem to work for the workspace, as illustrated by the following:
>> whos
Name Size Bytes Class Attributes
C 5x1 572 cell
S 7x1 9852 struct
ans 1x102 204 char
datimNow 1x20 40 char
mem 1x105 210 char
memory 1x81 162 char
status 1x1 8 double
>> S = whos()
S =
7×1 struct array with fields:
name
size
bytes
class
global
sparse
complex
nesting
persistent
Am I doing something wrong, or is there a better way to monitor variable space use during execution?
  2 Comments
dormant
dormant on 19 Jan 2024
OOps, I forgot to mention I am on Linux, so can't use the memory function.
Dyuman Joshi
Dyuman Joshi on 19 Jan 2024
Edited: Dyuman Joshi on 19 Jan 2024
"The option to store the output in a cell array doesn't seem to work for the workspace"
Maybe I am misunderstanding, but the outptut is a struct array.
You can get the data from the size field, corresponding to the variables in the name field.
Edit - Note that calling whos() multiple times in your code will lead to reduction in code efficiency.
From this particular documentation page- "Avoid functions that query the state of MATLAB such as inputname, which, whos, exist(var), and dbstack. Run-time introspection is computationally expensive."
@dormant, How many times is whos() called in your code? And do you just have to see which variable takes the most bytes for storage?

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 19 Jan 2024
Perhaps something like this —
A = magic(7);
B = string(randi(9, 4));
C = sin(2*pi*(0:0.01:1));
whos
Name Size Bytes Class Attributes A 7x7 392 double B 4x4 960 string C 1x101 808 double cmdout 1x33 66 char
S = whos;
Fields = fieldnames(S);
Contents = struct2cell(S);
whos_result = [cell2table(Fields) cell2table(Contents)]
whos_result = 9×5 table
Fields Contents1 Contents2 Contents3 Contents4 ______________ ____________ ____________ ____________ ____________ {'name' } {'A' } {'B' } {'C' } {'cmdout' } {'size' } {[ 7 7]} {[ 4 4]} {[ 1 101]} {[ 1 33]} {'bytes' } {[ 392]} {[ 960]} {[ 808]} {[ 66]} {'class' } {'double' } {'string' } {'double' } {'char' } {'global' } {[ 0]} {[ 0]} {[ 0]} {[ 0]} {'sparse' } {[ 0]} {[ 0]} {[ 0]} {[ 0]} {'complex' } {[ 0]} {[ 0]} {[ 0]} {[ 0]} {'nesting' } {1×1 struct} {1×1 struct} {1×1 struct} {1×1 struct} {'persistent'} {[ 0]} {[ 0]} {[ 0]} {[ 0]}
MemoryCell = whos_result(strcmp(whos_result.Fields,'bytes'), :)
MemoryCell = 1×5 table
Fields Contents1 Contents2 Contents3 Contents4 _________ _________ _________ _________ _________ {'bytes'} {[392]} {[960]} {[808]} {[66]}
Total_Variable_Memory_Used_Bytes = sum(cellfun(@sum, table2array(MemoryCell(:,2:end))))
Total_Variable_Memory_Used_Bytes = 2226
.
  2 Comments
Steven Lord
Steven Lord on 22 Jan 2024
Rather than convert the struct into multiple cell arrays and displaying one table variable per workspace variable, I'd display one table row per workspace variable instead.
A = magic(7);
B = string(randi(9, 4));
C = sin(2*pi*(0:0.01:1));
T = struct2table(whos)
T = 4×9 table
name size bytes class global sparse complex nesting persistent __________ ________ _____ __________ ______ ______ _______ __________ __________ {'A' } 7 7 392 {'double'} false false false 1×1 struct false {'B' } 4 4 960 {'string'} false false false 1×1 struct false {'C' } 1 101 808 {'double'} false false false 1×1 struct false {'cmdout'} 1 33 66 {'char' } false false false 1×1 struct false
Then you can call whatever functions you want on the variables.
areAnyVariablesSparse = any(T.sparse)
areAnyVariablesSparse = logical
0
Note that simply summing up the bytes variable is not necessarily going to give you the total amount of memory used by MATLAB for those variables (copy-on-write, for example) but if you're looking for a quick approximation:
B = sum(T.bytes)
B = 2226
Star Strider
Star Strider on 22 Jan 2024
@Steven Lord — Using struct2table is definitely more efficient. I don’t use struct arrays very often, so I didn’t consider using it.

Sign in to comment.

More Answers (2)

Hassaan
Hassaan on 19 Jan 2024
The whos command by itself displays the information in the command window, but it doesn't return that information directly to a variable. To store this information in a variable, you need to use the evalin function with 'base' as the first argument, which evaluates the whos command in the base workspace and captures its output.
% Store the information about workspace variables in a struct array
workspaceVars = evalin('base', 'whos');
% Now you can process workspaceVars as needed
% For example, to display the names and sizes of the largest variables:
for i = 1:length(workspaceVars)
fprintf('Variable Name: %s, Size: %d bytes\n', workspaceVars(i).name, workspaceVars(i).bytes);
end
% You can sort them by size if you want to focus on the largest variables
[~, sortedIndices] = sort([workspaceVars.bytes], 'descend');
sortedVars = workspaceVars(sortedIndices);
% Display the sorted information
for i = 1:length(sortedVars)
fprintf('Variable Name: %s, Size: %d bytes\n', sortedVars(i).name, sortedVars(i).bytes);
end
-----------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
  • Technical Services and Consulting
  • Embedded Systems | Firmware Developement | Simulations
  • Electrical and Electronics Engineering
It's important to note that the advice and code are based on limited information and meant for educational purposes. Users should verify and adapt the code to their specific needs, ensuring compatibility and adherence to ethical standards.
Feel free to contact me.

dormant
dormant on 22 Jan 2024
Thank you to all answerers.
The problem turned out to be something that I could not diagnose with whois. The "culprit" was using mesh to plot a matrix that was far bigger than the screen resolution. That induced a memory overload and the system killed MATLAB.
I now decimate the matrix before plotting, and it seems to solve my problem.

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Tags

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!