One thing I completely forgot about was that MoPub will use a 30mb cache in memory by default. So for me my app was running at 50mb memory and went up to 80-90mb but did not go further.
(The following code is for creating a native ad without using an adapter). If you want to use the adapter, following the official instructions as they work ok, and memory only goes up by 30-40mb max.
I can show you my code, hopefully it may help you 
First I made sure my fragment implemented MoPubNative.MoPubNativeNetworkListener:
public class myFragment extends Fragment implements MoPubNative.MoPubNativeNetworkListener {
Then this following code creates the native and adds it to a container in my layout after I call nativeInit() . The nativeAdContainer is a LinearLayout inside my fragment layout that I use to hold the native ad.
public void nativeInit() {
if (null != getActivity()) {
MoPubNative mMoPubNative = new MoPubNative(getActivity(), "yourPlacementID", this);
ViewBinder viewBinder = new ViewBinder.Builder(R.layout.i_native_banner_ad)
.mainImageId(R.id.native_banner_image)
.iconImageId(R.id.native_banner_logo)
.titleId(R.id.native_banner_title)
.textId(R.id.native_banner_description)
.privacyInformationIconImageId(R.id.native_banner_ad_privacy_information_icon_image)
.callToActionId(R.id.native_banner_cta)
.build();
MoPubStaticNativeAdRenderer adRenderer = new MoPubStaticNativeAdRenderer(viewBinder);
mMoPubNative.registerAdRenderer(adRenderer);
final EnumSet<RequestParameters.NativeAdAsset> desiredAssets = EnumSet.of(
RequestParameters.NativeAdAsset.TITLE,
RequestParameters.NativeAdAsset.TEXT,
RequestParameters.NativeAdAsset.ICON_IMAGE,
RequestParameters.NativeAdAsset.CALL_TO_ACTION_TEXT);
RequestParameters requestParameters = new RequestParameters.Builder()
.desiredAssets(desiredAssets)
.build();
mMoPubNative.makeRequest(requestParameters);
}
}
@Override
public void onNativeLoad(NativeAd nativeAd) {
LLog.e(TAG, "Native Loaded");
if (null != getActivity()) {
View mView = nativeAd.createAdView(getActivity(), null);
if (null != mView) {
nativeAd.renderAdView(mView);
nativeAd.prepare(mView);
if (null != nativeAdContainer) {
nativeAdContainer.removeAllViews();
nativeAdContainer.addView(mView);
nativeAdContainer.setVisibility(View.VISIBLE);
}
}
}
}
@Override
public void onNativeFail(NativeErrorCode errorCode) {
if (null != nativeAdContainer) {
nativeAdContainer.removeAllViews();
nativeAdContainer.setVisibility(View.GONE);
}
}
With this code my memory usage does not go above 80mb from 50mb because MoPub only uses 30mb cache by default.
I went a step further because I found onPause the memory was not released. So I made the following code in my OnPause method of the fragment.
if (null != nativeAdContainer) {
nativeAdContainer.removeAllViews();
Networking.clearForTesting();
}
So on pause the objects are forced to be released and on the next garbage collection the memory is released.
And yes Networking.clearForTesting() does work in a live version, however not sure if they will always have this method in the SDK in the future. It’s only optional if you want to keep memory usage low onPause.
Hope it helps!