About Memory Usage
PSPDFKit can deal with very complex documents, but since Android is a platform with restricted memory and rendering PDFs can be quite a memory consuming tasks, there are certain limits in what you can do before the OS is going to kill the app. The limits are based on many factors not limited by device memory, manufacturer and Android OS version. In general more high end devices will be able to work faster with more complex documents. We're using quite a lot of custom code so that old devices still work fine though.
Note that PSPDFKit has been designed to use a lot of memory for caching and to make things more fluid. We don't know how much is available, so PSPDFKit will adapt and restrict usage when we get low memory notifications. This is a normal behavior and nothing you should be worried about. However if you're getting lots and lots of warnings and the system will kill the app thereafter, then you should look into the issue.
Here's a checklist what you can do if get crashes related to memory pressure:
Are you using multiple
PdfFragment's at once? Each takes a considerable amount of memory, so keeping multiple ones on the screen at the same time can put a lot of memory pressure on the system. We suggest not using more than two at the same time (so 2 as a split-screen is ok, showing 4 might be an issue).
AndroidManifest.xml. This will create your application's processes with a large Dalvik heap.
Ensure you don't have other memory leaks in your app. Google's article Investigating your RAM Usage provides a lot of great resources.
Certain PDFs might simply be too complex to render. This is a rare issue, but if your PDF is really complex (and with complex, this doesn't necessarily mean large), you might need to make your PDF simpler or split things across multiple pages.
Make sure that you don't create multiple instances of the same
PdfDocument. For complex documents, those objects manage considerable amount of memory, and it's very wasteful to destroy/recreate them, especially if the document has many pages.
Memory usage for Image decompressing
Rendering images requires them to be decompressed into memory. Images in PDF are usually stored as separate objects (called "XObject") and contain the raw binary data. This data can be compressed as JPEG, JBIG2, JPEG2000/JPX, RAW or various other supported formats). Before images can be rendered, this data needs to be loaded and decompressed into memory.
For example, let's look at an image that is 4000x3000 pixels large and saved with colors. This would result in following memory usage:
memory_used = 4 * width * height 4*4000*3000/1024 = ~45.77 MB.
Why 4? ARGB is the most common way to save images, so there are 4 bytes required for every pixel.
This is more of an issue on mobile devices, where no swap space exists. Thus, there's a hard limit on the available amount of memory, which also has to be shared with other applications and the operating system itself.
There are far too many Android devices to list them all, but here are some popular ones and the amount of RAM available. To check the RAM of your own phone, go to Settings -> About Phone.
- Samsung Galaxy [Grand|Core] Prime [Neo Plus], Samsung Galaxy J1/S3 [Mini], Motorola Moto G: 1 GB
- Samsung Galaxy J2/J5/J7/Grand2: 1.5 GB
- Nexus 9, Samsung Galaxy S4/S5/A5, Samsung Galaxy Note2: 2 GB
- Samsung Galaxy Tab S2, Samsung Galaxy Note3/4, Samsung Galaxy S6 [Edge], Google Pixel C: 3 GB
- Samsung Galaxy Note5/7: 4 GB
- OnePlus 3: 6 GB
(This list is roughly based on the Top Android Phones as of July 2016)
Devices with hi-dpi ("retina") screen have more pixels and thus have a higher memory consumption. For example Nexus 9 tablet has screen with resolution 2048×1536, so one full-screen image requires 12 MB of memory.
The Android Operating System closely monitors memory usage and will terminate processes that cross the limit. Google's documentation about Managing Your App's Memory is a great starting place to learn more about this. The Android ActivityManager's LowMemoryKiller can be customized so available memory might be different even on devices with the same amount of RAM available, depending on manufacturer, user, 3rd-party apps and Android OS version.
When overall device memory is getting low apps are notified. PSPDFKit correctly handles these notifications and frees up not critical resources in such situations. This does not work if the application requests a large block of memory at once - which is what is required to decompress an image. If PSPDFKit detects an image that would require more memory than what is safe to be allocated, we log a warning, instead of taking the risk to be killed.
"Couldn't load image: image size too big (X bytes, maximum allowed is X)"
Adobe Acrobat has an Optimize... feature that allows you to recompress images to take up less space. Note that the raw image size can still be very large, even though in the PDF the image appears to be downscaled and small. Use Edit->Preflight... and then select the "List page objects" option.
For example, here is a PDF that has an image with 4672x13495 pixels, taking up 4672134954 = 240,5 MB.
You can use the PDF Optimizer feature of Adobe Acrobat Pro (File -> Save as Other -> Optimized PDF...) to reduce the image size (ppi, Pixels per inch. To learn more, read our Optimize PDF for mobile rendering article.