Randomly Out of memory errors precedeed by JsVarOverflow #454
Replies: 45 comments
-
Posted at 2015-09-18 by @gfwilliams Ahh, ok - so the reason GPS and Serial4 are so big is because they're linking to each other... So I guess Serial4 has a callback that references GPS, and vice versa. What about trying:
... and maybe drill down with |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @allObjects Very interesting. When I worked with a ublox 6M moudule, I had irregularities too: sometimes some values in a sentence were missing and lead to errors in conversion to a number. I used the standard Espruino GPS moudule after it was minimally modified to allow to have custom handlers. I did not think of stripping down the output scope in ublox moudule. Glancing over the GPS_ext12.js code I wondered about the extra arguments in setTimeout() invocation in start_stop_nmea(), ~ line 110. Can you explain? Btw, I like the function/method-creation approach by using the sentence attribute name as the signature and then have a content type addressed detail handling. The not so liked part is the eval()... but the heck: if code can create programmatic code based on declarations, why not go for it! Did you consider to run the function generation in a preprocess step and output the source, and then use that source explicitely? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @gfwilliams
see this - you can now pass a function in, and have |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @allObjects @gordon, thanks... I'm obviously damaged by working for too long for too much in lowest-common-(browser-)denominator settings... ;) With these extra parameters, a plain, naked function reference can be used. If this is needed in it, a myFunction.bind(thisContext) eliminates the need for an extra anonymous functions ... |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by asez73 Well, the eval part is doing programmaticaly what i found cumbersome. The real goal is to minimise any computation done in the serial.on loop and still provide any data of interest in a naturally javascript suitable for further computations and efficient data storage. It's still in progress. As a matter of fact, I prefer to pre-process on launch as much as possible and then delete any no more usefull functions or objects. This reduces the dependancy of this program to predefined gps board behaviour. About incomplete sentences. from the device, it just drops any outdated sentence even if it is beeing send through the serial link, with no eol, just the $ before the next sentence. I ended with a systematic checksum verification, discarding any unvalid sentence before any further computation. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @allObjects I was thinking about preprocessing even before the launch - I assume you refere with launch to connect and what it does: I separate step, the source generation is run, and it's output is used as part of the .js file. The muting of unwanted sentences - or config which sentences - the gps modules has to send, can still happen when connecting. Doning so does not need the pre-config the device seperately. On the other hand, if memory get's tight, this will be a nice option. I have experienced memory shortages quit quickly, and resorted to similar aproaches: have the config info not in well structured objects, but as single string(s) with comma (or space) separation of the individual values. Processing with a *.split(",") uses only temporary memory. My example was the description of a pac-man board/maze, drawing it on a 320x240 ILI#### controled display , and boundary checking for the 'moving parts', etc... In the end I had even to come up with an encodeing to keep the code/data still readable but using up only one byte. Finding out 'quickly' what to spend processing time on and what to drop is a nice approach. Do you have figures/stats how much - %-wise - is dropped? Even with the good data, I had to optimize more: a) only changed data I did render and send to the display, and b) building up of the display is parts by parts to stay 'within the loop' of 1 update/second. Using your approach of 'quieting' the module would have been a great help. Enjoyed very much 'listening' to your code and its style - like a good piece of music! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by asez73 Yes, you are probably right and I have to understand something like 'this' in event context... Here is the result of your proposition. Note on the last commands that I failed to list the event handlers defined with gps.on and Serial4.on...
And
Digging inside failed due to events handlers names...
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @allObjects 'this' represents the default runtime context from within a function is invoked - event or otherwise. If the function is bound though to an object before invocation with |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by asez73 Yes, I have memory shortages in sight and actually, the main problem seems to be in the events handlers Serial4.on and gps.on. cross referencing each other.... Which is still more a hope than a fact. About figures, this is the 12th iteration of code.
Finally, I used, and adapted, my Chrono prototypes to get the processor charge in % of the time: that is rather than looking at individual timing of a nmea sentence, look at the global timing of the treatment of all of them. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @gfwilliams Hmm, that's hard to narrow down. Could you try edit: actually forget that - it was the input buffer overflowing because of the time taken to execute the constructor. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by asez73 I haven't yet used it on the pico. However, except for the serial pins definitions it should run all the way... Ok, now the trace(Serial4) really prints everything. Let's hope we can understand what's going on from that. edit: Reading further this trace, I was wondering:
Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @gfwilliams Is that trace from when it has the memory leak? I don't see anything obvious in there (but it's hard to see!) - although Perhaps outputting the data from Also, do you get the memory leak with non- |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by @gfwilliams
Yes, because of the scope chain from functions that you have defined in You could:
Yes, they're in |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by asez73 Yes, you are right. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-18 by asez73 Ok, that's clear now: I have to review the connect function and make it much more memory and time savy. So far, the "compiled" functions have not been a problem since you solve the webide getting confused about the order of returned compiled function last week. edit: Here is a memory status taken from just after the trace(Serial4) to now.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-21 by cwilt I have not explored the SD file writing routines to see how well handles JSON. Was just a passing thought. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-21 by @allObjects
Encountering this
Similar approach for function signatures incl. return type. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-22 by @gfwilliams
Yes, it's executed after the Serial events have been processed - that could change at some point in the future though. However the 'real-time' handling of Serial events may do what you need anyway. When it calls your Suppose you have a stream of data
But if you have a slow handler, it'll get called with more data:
I guess perhaps by splitting off your handling you could detect whether you had more than one GPS sentence waiting to be processed and could voluntarily drop one rather than filling up the input buffer. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-22 by @allObjects I think the batching is the better idea then try to have handlers that are actually fast enough to do the job. ...batching even to a custome defineable delimiter... or number of bytes received. An application (timeout) triggered getData(callbackData,callbackNoData) - w/ synchronous callbacks - could be an option to check for and get data... For the SDI-12 protocol I was thinking of having a similar 'buffering middle-layer' that gets pulled data from the app in desired chunks... This allows failing patterns to drop before they even go into the buffer. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-24 by asez73 Hello, |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-24 by asez73 Well, gps is all about real time and position... |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-24 by @allObjects Yep, it is a great help in monitoring your Espruino... to see what is going on... The challenge is that it 'interferes' timewise, because code is exectuted on an interval bases that consumes cycles to get the data and send it over the Serial/USB/Console to the testing tool. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-26 by asez73 @gordon and all others interested:
The context object above is a global object created outside of the parseHandlers function. The joined file is actually the parsing function that creates the gps object with its nmea sentences as methods. You then can call gps.GPGGA(d) were d is the array, comma splitted, resulting of the nmea string received after checksum and dollar having been removed. Once intialised, you just could delete parseHandlers function which will free the memory space it used: around 650 jsVars... While gps object is less than a 100 jsVars.... So, so...Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-26 by @gfwilliams That's great! Thanks for posting up! Do you think there's anything that could be done to warn users when this is happening or help them detect it? I guess |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-26 by asez73 Definitly yes, |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-26 by @allObjects @asez73, where do you draw the line 'real time'? Batching to simplify in the internal processing does not mean it is not real time for the user. Batching was also meant for just collecting all the received bytes until they make a reasonable gps sentence. This process should not be visible to the application. When look at @gordon's implementation of the GPS moudle, it has a continuous buffering of received data. When something is ready to put into the buffer it is just appended, and when a sentence is found, it removes that part from the buffer and calls the callback. In other words, the filling of the buffer happens in chunks not necessarily aligned with the calling of the callback. If the buffering happens in pieces smaller than a complete sentence callback is not called on recption/buffering event. If more than one sentence is received, then the code loops around invocation of the callback until no complete sentence is found anymore in the buffer. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-26 by asez73 Real time, normally, means with a known delay between this instant of the event and the start of the routine in charge of handling the event. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-26 by @allObjects
That's right, It all depends.
There are the layers... such as the comm layer byte by byte, bytes by bytes, sentence by sentence, processing sentence by sentence, etc. I think the solution is optimal to have each layer to be as efficient as possible. I see your point that you actually could even start to process a single value from a sentence as soon as available. For certain things that can make sense. On the other hand, to make a "final" decision, you nead 3 things in a 3D world. I think your approach to tailor first which sentences and then do the same for which values in the remaining sentences, that gets you where you want to be: as realtime as possible, realtime as to the point: as soon as the information is available. For storing the values? Do you already have a solution? If you can process the pertine data in time, how much time do you have left to store it?... for example: in sequences of deltas? reduced granularity? encoded to use minimal space? Any processing requires additional time before storing. 100ms is not much the get everything done... Your app may become the first multi-PICO solution... or you switch over to the Propeller. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-09-27 by asez73 Well, you spotted it : To my opinion and so far identified needs, I would say that the "low level" realtime layer separates the gps data stream from the use of these data. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-10-01 by @gfwilliams I've now made
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2015-09-18 by asez73
So, I just have a problem which cause is very unclear to me.
There are no memory leakage for hours and it suddenly appears, or most of the time, never happens.
And that's without any change to the source code of course.
Whenever it happens, it is immediately precedeed by Jsvar length problems...
I do not see why it happens, except either some interpreter internal problem or some real time kind of problem.
I suspect a serial buffer overflow as the serial speed is set to 115200 bauds and the ublox NEO-6M sends data in chuncks which can be fairly long (115 chars for PUBX,00 nmea sentence for instance).
So, my code now reduces the types of nmea sentences that the ublox gps device can send. This is a ublox feature which allows to inhibate nmea sentences by sending some specific commands to the ublox. This greatly helps as the error did not showed again since this.
Anyway, following @gordon suggestions about debugging, I had the following uncoherent results.
Specifically, the gps and Serial4 objects should not be that big and even fit to RAM if I don't misunderstand the figures.
The source code file is joined.
Attachments:
Beta Was this translation helpful? Give feedback.
All reactions