Log a message if we are most likely out of memory.
Check for errors when allocating JSON objects.

This avoids a hard crash when we are OOM.
Shorten CAN message queue to avoid running out of memory.

See #164 - need to determine optimal size that's not so big that we
can't add any more signals.
Split the representation of CAN messages into 2 variants to save RAM.

We never fill in most of the metadat in the former CanMessage struct
when we're just using it to hold an ID and data field for a buffered
message, so instead we split it into two variants - the compact
CanMessage for these buffers, and the larger CanMessageDefinition for
storing the metadata.

This saves RAM in both the CanBus.sendQueue and CanBus.receiveQueue, and
it makes the definition of CAN messages smaller by 4 bytes (no 'data'
field) - further savings adding to #162.
Only log stats for pipeline or bus if messages have been received/sent.