[Serializer] Handle circular references

| Q             | A
| ------------- | ---
| Bug fix?      | Yes: avoid infinite loops. Allows to improve #5347
| New feature?  | yes (circular reference handler)
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| License       | MIT
| Doc PR        | not yet

This PR adds handling of circular references in the `Serializer` component.
The number of allowed iterations is configurable (one by default).
The behavior when a circular reference is detected is configurable. By default an exception is thrown. Instead of throwing an exception, it's possible to register a custom handler (e.g.: a Doctrine Handler returning the object ID).

Usage:
```php
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;

class MyObj
{
    private $id = 1312;

    public function getId()
    {
        return $this->getId();
    }

    public function getMe()
    {
        return $this;
    }
}

$normalizer = new GetSetMethodNormalizer();
$normalizer->setCircularReferenceLimit(3);
$normalizer->setCircularReferenceHandler(function ($obj) {
    return $obj->getId();
});

$serializer = new Serializer([$normalizer]);
$serializer->normalize(new MyObj());
```
Replacing the $context['circular_reference_limit'] array by an SplObjectStorage should prevent the many copies that currently occurs along the recursive walk.