First of all: explanations aside, it still depends a lot on your requirements, environment settings ...
The view state is stored in a hidden field that appears as the <input /> in the final HTML sent to the browser. When the user initiates the postback (Button Click, etc.), the data is sent back to the server as part of the provided form data.
If you store a large amount of data in ViewState, you will have to incur a fine when the user tries to load the page, because all such data will be part of your HTML, and also when the user tries to submit the form, because again this data will be sent back to the server.
In addition, ViewState is easily lost. It is saved only as long as the user submits the form. If the user clicks a hyperlink to another page, the form is not submitted, and therefore the data contained in the ViewState is lost.
It is recommended to use ViewState if the data is relatively small.
If we look at security options, ViewState data will be encoded in base64, which can be easily decoded. This is a classic example of a website hack, so cross-check what data you store. Although you can solve this problem by setting EnableViewStateMac to true.
For large amounts of data, a session is a good option. If you can detect when a user is executed with a specific data block, set the Session variable to null to withstand the memory overhead. You cannot always do this, but the session will expire and the memory will be automatically fixed. Reducing the session timeout can also help, but set it according to your needs.
In addition, the data in the session is actually present on the web server between page loads. This helps reduce page size, but only to use session id.
One recent option is to use Caching.Check MSDN here for best caching practices.