The fields that you populate in ctx are deleted when the computational graph itself is deleted.
You can see it in the following code snippet:
import torch
from torch.autograd import Variable, Function

import weakref

my_ref = None

class MyFunc(Function):
    @staticmethod
    def forward(ctx, inp):
        a = torch.rand(2)
        global my_ref
        my_ref = weakref.ref(a)
        ctx.a = a
        print("Ref in forward: ", my_ref())
        return inp.clone()

    @staticmethod
    def backward(ctx, gO):
        print("Ref in backward: ", my_ref())
        return gO.clone()


def get_loss():
    inp = Variable(torch.rand(10), requires_grad=True)
    out = MyFunc.apply(inp)
    return out.sum()

loss = get_loss()
print("Ref before backward: ", my_ref()) # returns the Tensor
loss.backward()
print("Ref after backward: ", my_ref()) # returns the Tensor
del loss
print("Ref after del loss: ", my_ref()) # returns None