DTrace can do some of that (at least in Solaris, you’ll have to try it out yourself on macOS). The vm
provider has probes named fspgin
, fspgout
, and fsfree
which fire when FS-backed pages are paged in or out of memory or are freed if they’re unmodified, respectively. There’s also a more general one called maj_fault
which fires whenever a page fault results in IO.
The only problem is that DTrace doesn’t give you a way to get back to the filename from those probes, which might be ok if you’re mainly page faulting on a single file, or might be really annoying if you’re trying to figure out which file is the one getting paged. However, you can still get the execname
or pid
of the process that’s causing the page fault though, in case that helps.
Here’s where you can see the documentation for the vm
provider. There are some example scripts there, but this one is probably the nicest to use:
vminfo:::maj_fault,
vminfo:::zfod,
vminfo:::as_fault
/execname == "soffice.bin" && start == 0/
{
/*
* This is the first time that a vminfo probe has been hit; record
* our initial timestamp.
*/
start = timestamp;
}
vminfo:::maj_fault,
vminfo:::zfod,
vminfo:::as_fault
/execname == "soffice.bin"/
{
/*
* Aggregate on the probename, and lquantize() the number of seconds
* since our initial timestamp. (There are 1,000,000,000 nanoseconds
* in a second.) We assume that the script will be terminated before
* 60 seconds elapses.
*/
@[probename] =
lquantize((timestamp - start) / 1000000000, 0, 60);
}
This prints out a timeline of memory activity for each type of fault, and the docs explain it in a little more detail.