-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: reduce memory use in test stringbytes #3697
Conversation
The fix looks good, but why did you change the assertions in the catch blocks? |
I'm not sure if there are disadvantages but I thought it could be helpful to rethrow the original exception in case a different exception occurs.
Instead of
|
lgtm, I do think re-throwing makes sense so that we can see the original exception |
The reason behind the current implementation is that it helps account for the additional space in the v8 heap necessary to store all the strings that are created. I'd say the most reliable approach would be to run gc right after the try/catch. |
@trevnorris I made some changes to the at-max test to use --expose-gc based on some other tests. Can you please take a look before I update the other tests? |
@thinkingdust Nice. Like the way you did that. |
Thanks. I've pushed the changes to the other files. I also ran the tests on the Windows machine again and they always either skip or pass now as desired. |
I'd squash the commits and include a note about why the change to throwing instead of assert. Other than that, LGTM. |
} catch(e) { | ||
assert.equal(e.message, 'Invalid array buffer length'); | ||
if (e.message != 'Invalid array buffer length') throw (e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd add a comment explaining you don't use assert in order to preserve the original exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and a femto style nit: !==
Some style nits but basic premise LGTM. |
@bnoordhuis Thanks for the suggestions, updated. |
Kicked off a new CI run... the previous run (693) was returning a 404: https://ci.nodejs.org/job/node-test-pull-request/712/ |
LGTM |
I think there is only one related failure. |
Maybe just exclude this test on low memory machines? Something like if (os.totalmem() <= 512000000 /* 512mb */) {
// bail
return;
} (note: Edit actually maybe |
So if I understand correctly @thinkingdust we still saw a failure in the test even after the PR ? |
It's a 404 now but there was a timeout failure in one of the tests on Raspberry Pi. |
@thinkingdust v8 doesn't have anything to do with memory allocation with Buffers. It's a simple |
I added a freemem check for the at-max test and it works fine on my Linux machine. I can try it on the Windows machine tomorrow. Is this use of freemem reliable enough to remove the try catch blocks? |
Using the freemem check works to always skip or pass on the original Windows machine. |
@trevnorris I changed the at-max test to check using freemem instead of try/catch and gc. If that looks okay to you I'll update the other files too. |
Another failure on ARM today: https://ci.nodejs.org/job/node-test-binary-arm/81/RUN_SUBSET=4,nodes=pi2-raspbian-wheezy/console Would be nice to get the fix in. |
@trevnorris ... can you take another look at this when you get a moment? :-) |
Some things: I think freemem may include cache and possibly swap, but I can confirm totalmem is just the hardware ram. I think my original suggestion of just skipping on 512mb ram machines (ontop of the other protections) would be best. |
Had a follow up to @Fishrock123's comment, but still LGTM. |
@trevnorris @Fishrock123 I added common.kMaxTestMemUsage. Can you take a look? |
LGTM |
Correct me if I'm wrong but I think |
Or at least an environment variable. |
@Fishrock123 Don't think so. We've honestly just selected the value based on past fail cases. Can't see why it would need to be configurable and/or need to be set from C++. |
Ah, ok. I think |
So make the export simply a boolean? Can't say I'm against that, but also don't want to make EDIT: auto-select fail |
Rubber-stamp LGTM |
🎆 ✨ |
LGTM |
@thinkingdust i'm having a hard time segmenting these commits into discrete changes. Mind if I squash them all, or would you like to take care of it? |
The current implementation of tests for strings with length at or exceeding kStringMaxLength allocate a temporary buffer inside a try block to skip the test if there is insufficient memory. This commit adds an invocation of the garbage collector after the temporary buffer is allocated so that memory is freed for later allocations. Change the corresponding catch block to rethrow the original exception instead of asserting the exception message to provide more information about the exception. Add an additional check before trying to allocate memory to immediately skip the test on machines with insufficient total memory.
I think 1 commit works. Squashed. |
Thanks much! Landed in a40b9ca |
The current implementation of tests for strings with length at or exceeding kStringMaxLength allocate a temporary buffer inside a try block to skip the test if there is insufficient memory. This commit adds an invocation of the garbage collector after the temporary buffer is allocated so that memory is freed for later allocations. Change the corresponding catch block to rethrow the original exception instead of asserting the exception message to provide more information about the exception. Add an additional check before trying to allocate memory to immediately skip the test on machines with insufficient total memory. PR-URL: #3697 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaël Zasso <mic.besace@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
The current implementation of tests for strings with length at or exceeding kStringMaxLength allocate a temporary buffer inside a try block to skip the test if there is insufficient memory. This commit adds an invocation of the garbage collector after the temporary buffer is allocated so that memory is freed for later allocations. Change the corresponding catch block to rethrow the original exception instead of asserting the exception message to provide more information about the exception. Add an additional check before trying to allocate memory to immediately skip the test on machines with insufficient total memory. PR-URL: #3697 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaël Zasso <mic.besace@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
The current implementation of tests for strings with length at or exceeding kStringMaxLength allocate a temporary buffer inside a try block to skip the test if there is insufficient memory. This commit adds an invocation of the garbage collector after the temporary buffer is allocated so that memory is freed for later allocations. Change the corresponding catch block to rethrow the original exception instead of asserting the exception message to provide more information about the exception. Add an additional check before trying to allocate memory to immediately skip the test on machines with insufficient total memory. PR-URL: #3697 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaël Zasso <mic.besace@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
The current implementation of tests for strings with length at or exceeding kStringMaxLength allocate a temporary buffer inside a try block to skip the test if there is insufficient memory. This commit adds an invocation of the garbage collector after the temporary buffer is allocated so that memory is freed for later allocations. Change the corresponding catch block to rethrow the original exception instead of asserting the exception message to provide more information about the exception. Add an additional check before trying to allocate memory to immediately skip the test on machines with insufficient total memory. PR-URL: #3697 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaël Zasso <mic.besace@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
The current implementation of tests for strings with length at or exceeding kStringMaxLength allocate a temporary buffer inside a try block to skip the test if there is insufficient memory. This commit adds an invocation of the garbage collector after the temporary buffer is allocated so that memory is freed for later allocations. Change the corresponding catch block to rethrow the original exception instead of asserting the exception message to provide more information about the exception. Add an additional check before trying to allocate memory to immediately skip the test on machines with insufficient total memory. PR-URL: nodejs#3697 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaël Zasso <mic.besace@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
When I run the string bytes tests dealing with strings of length kStringMaxLength or more on a Windows test machine with 4GB memory I see the tests skipped or failed with the following outputs respectively.
1..0 # Skipped: intensive toString tests due to memory confinements
RangeError: Invalid array buffer length
The code being used to determine if the test should be skipped is:
A problem with this approach is that the garbage collector does not necessarily run between the tried allocation and the necessary allocations later. That means that even though no exception is thrown in the try block since the machine has enough memory, the later allocations fail since the memory is now taken.
To verify this, I ran the test with
Release\node.exe --expose-gc test\parallel\test-stringbytes-external-at-max.js
to exposeglobal.gc()
which I used after the try catch block. With this setup the test would either skip or succeed as desired.To solve the issue, I removed the Buffer allocations that were used to check if the tests should be skipped and moved the actual Buffer allocations into the try block so the test can still be skipped if memory allocation fails here. The tests should now use less total memory and be less likely to be skipped and more importantly, less likely to fail due to a memory constraint when they are not skipped.