whos - I can't capture the output

10 visualizaciones (últimos 30 días)
dormant
dormant el 19 de En. de 2024
Comentada: Star Strider el 22 de En. de 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 comentarios
dormant
dormant el 19 de En. de 2024
OOps, I forgot to mention I am on Linux, so can't use the memory function.
Dyuman Joshi
Dyuman Joshi el 19 de En. de 2024
Editada: Dyuman Joshi el 19 de En. de 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?

Iniciar sesión para comentar.

Respuesta aceptada

Star Strider
Star Strider el 19 de En. de 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 comentarios
Steven Lord
Steven Lord el 22 de En. de 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 el 22 de En. de 2024
@Steven Lord — Using struct2table is definitely more efficient. I don’t use struct arrays very often, so I didn’t consider using it.

Iniciar sesión para comentar.

Más respuestas (2)

Hassaan
Hassaan el 19 de En. de 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 el 22 de En. de 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.

Categorías

Más información sobre Data Type Conversion en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by