Memory Usage of the AP .Net

The memory usage in the AP .Net for different policy sizes with a sample.

Using the Sample .Net Application to Test Memory Usage for Policies

This article provides information about memory requirements of the AP .Net. A sample .Net application is provided below. It can be used to test the memory requirements of policies of various sizes. Results of that testing are based on the memory usage of a single instance of a .Net process, excluding LogForwarder and RP Agent.

Sample application

The following is a sample .Net application.

using System;
using System.Collections.Generic;
using System.Text;
using Protegrity.Net;
using Protegrity.PException;

namespace APDotNetTest
{
    /**********************************************************************************************/
    /**
     * @class   Program
     *
     * @brief   A sample program for Application .NET Protector.
     *
     **************************************************************************************************/
    class Program
    {
        private const string dataElementName = "alphanum";
        private const string newDataElementName = "alphanumreprot";
        private const string userName = "policyuser";


        /**********************************************************************************************/
        /**
         * @fn  static void Main(string[] args)
         *
         * @brief   Main entry-point for this application
         *
         * @param   args    An array of command-line argument strings.
         **************************************************************************************************/

        static void Main(string[] args)
        { 
            try
            {
                /* Dispose() is a method defined by the IDisposable interface in .NET. 
                 * Its used to release unmanaged resources.
                 * .NET garbage collector only cleans up managed memory. If your class uses unmanaged resources, 
                 * you must clean them up manually  and thats what Dispose() is for.
                 * 
                 * ====================
                 * With using 
                 * ====================
                 * You're telling the compiler:
                 * "Create this object, and automatically call Dispose() on it 
                 * when it goes out of scope."
                 * This is called a using declaration, and it ensures that cleanup happens even if
                 * an exception occurs.
                 * 
                 * ======================
                 * Without using
                 * ======================
                 * You have to call dispose manually.
                 */

                using Protector protector = Protector.GetProtector();

                /**
                 * Sample input string data for single operations.
                 */
                string singleInput = "Hello Protegrity";
                byte[] singleByteInput = Encoding.UTF8.GetBytes(singleInput);

                Console.WriteLine("#########################################");
                Console.WriteLine("# Protegrity Application .NET Protector #");
                Console.WriteLine("#########################################\n");

                /**
                 * Calling GetVersion to print APDotNet sdk and Core version.
                 */
                Console.WriteLine(protector.GetVersion() + "\n");
                Console.WriteLine("--------------------------------------");
                Console.WriteLine("-     Single Protect API             -");
                Console.WriteLine("--------------------------------------");
                Console.WriteLine($"Input Data is:        {singleInput}\n");


                /**
                 * Use protector object to call single string Protect API.
                 */
                string protectedData = protector.Protect(singleInput, userName, dataElementName);
                Console.WriteLine("With String Data Type");
                Console.WriteLine("-----------------------");
                Console.WriteLine($"Protected Data is:    {protectedData}");

                /**
                 * Use protector object to call single string Unprotect API
                 */
                string unprotectedData = protector.Unprotect(protectedData, userName, dataElementName);
                Console.WriteLine($"Unprotected Data is:  {unprotectedData}\n");

                /**
                * Use protector object to call single string Reprotect API.
                */
                string reprotectedData = protector.Reprotect(protectedData, userName, dataElementName, newDataElementName);
                Console.WriteLine($"Reprotected Data is:  {reprotectedData}");

                /**
                 * Use protector object to call single string Unprotect API
                 */
                string unprotectReprotectedData = protector.Unprotect(reprotectedData, userName, newDataElementName);
                Console.WriteLine($"Unprotected Data is:  {unprotectReprotectedData}\n");

                /** 
                 * Use protector object to call single byte Protect API.
                 */
                byte[] byteProtectedData = protector.Protect(singleByteInput, userName, dataElementName);
                Console.WriteLine("With Byte Data Type");
                Console.WriteLine("----------------------");
                Console.WriteLine($"Protected Byte Data is:    {Encoding.UTF8.GetString(byteProtectedData)}");

                /**
                 * Use protector object to call single byte Unprotect API
                 */
                byte[] byteUnprotectedData = protector.Unprotect(byteProtectedData, userName, dataElementName);
                Console.WriteLine($"Unprotected Byte Data is:  {Encoding.UTF8.GetString(byteUnprotectedData)}\n");

                /**
                 * Use protector object to call single byte Reprotect API.
                 */
                byte[] byteReprotectedData = protector.Reprotect(byteProtectedData, userName, dataElementName, newDataElementName);
                Console.WriteLine($"Reprotected Byte Data is:  {Encoding.UTF8.GetString(byteReprotectedData)}");

                /**
                 * Use protector object to call single byte Unprotect API
                 */
                byte[] byteUnprotectReprotectedData = protector.Unprotect(byteReprotectedData, userName, newDataElementName);
                Console.WriteLine($"Unprotected Byte Data is:  {Encoding.UTF8.GetString(byteUnprotectReprotectedData)}");
                Console.WriteLine("\n");

                /**
                 * Sample bulk string input data
                 */
                string[] bulkInput = { "The Alpha-numeric token type tokenizes all alphabetic symbols (both lowercase and uppercase letters), as well as digits.", "Digits 0 through 9, Lowercase letters a through z, Uppercase letters A through Z", "alphanumeric data 1234567890 !@#$%^&* with special characters", "ALL THE CHARACTERS IN THIS STRING ARE UPPERCASE", "UPPERCASE WITH 1234567890 NUMBERS AND !@#$%^&*() SPECIAL CHARACTERS" };
                List<byte[]> byteBulkInput = new List<byte[]>(bulkInput.Length);

                Console.WriteLine("--------------------------------------");
                Console.WriteLine("-         Bulk Protect API           -");
                Console.WriteLine("--------------------------------------");

                Console.WriteLine("Input Data is:");

                /**
                 * Converting string data to byte data.
                 */
                for (int i = 0; i < bulkInput.Length; i++)
                {
                    Console.WriteLine($"{bulkInput[i]}");
                    byteBulkInput.Add(Encoding.UTF8.GetBytes(bulkInput[i]));
                }

                Console.WriteLine("\n");
                Console.WriteLine("With String Data Type");
                Console.WriteLine("----------------------");

                /**
                 * Use protector object to call bulk string Protect API
                 */
                Tuple<string[], int[]> bulkProtectedData = protector.Protect(bulkInput, userName, dataElementName);
                Console.WriteLine("Protected Data is: ");
                for (int i = 0; i < bulkProtectedData.Item1.Length; i++)
                {
                    Console.WriteLine(bulkProtectedData.Item1[i] + " " + bulkProtectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                /**
                 * Use protector object to call bulk string Unprotect API
                 */
                Tuple<string[], int[]> bulkUnprotectedData = protector.Unprotect(bulkProtectedData.Item1, userName, dataElementName);
                Console.WriteLine("Unprotected Data is: ");
                for (int i = 0; i < bulkUnprotectedData.Item1.Length; i++)
                {
                    Console.WriteLine(bulkUnprotectedData.Item1[i] + " " + bulkUnprotectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                /**
                 * Use protector object to call bulk string Reprotect API
                 */
                Tuple<string[], int[]> bulkReprotectedData = protector.Reprotect(bulkProtectedData.Item1, userName, dataElementName, newDataElementName);
                Console.WriteLine("Reprotected Data is: ");
                for (int i = 0; i < bulkReprotectedData.Item1.Length; i++)
                {
                    Console.WriteLine(bulkReprotectedData.Item1[i] + " " + bulkReprotectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                /**
                * Use protector object to call bulk string Unprotect API
                */
                Tuple<string[], int[]> bulkUnprotectReprotectedData = protector.Unprotect(bulkReprotectedData.Item1, userName, newDataElementName);
                Console.WriteLine("Unprotected Data is: ");
                for (int i = 0; i < bulkUnprotectReprotectedData.Item1.Length; i++)
                {
                    Console.WriteLine(bulkUnprotectReprotectedData.Item1[i] + " " + bulkUnprotectReprotectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                Console.WriteLine("With Byte Data Type");
                Console.WriteLine("----------------------");

                /**
                 * Use protector object to call bulk byte Protect API
                 */
                Tuple<List<byte[]>, int[]> byteBulkProtectedData = protector.Protect(byteBulkInput, userName, dataElementName);
                Console.WriteLine("Protected Data is: ");
                for (int i = 0; i < byteBulkProtectedData.Item1.Count; i++)
                {
                    Console.WriteLine(Encoding.UTF8.GetString(byteBulkProtectedData.Item1[i]) + " " + byteBulkProtectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                /**
                * Use protector object to call bulk byte Unprotect API
                */
                Tuple<List<byte[]>, int[]> byteBulkUnprotectedData = protector.Unprotect(byteBulkProtectedData.Item1, userName, dataElementName);
                Console.WriteLine("Unprotected Data is: ");
                for (int i = 0; i < byteBulkUnprotectedData.Item1.Count; i++)
                {
                    Console.WriteLine(Encoding.UTF8.GetString(byteBulkUnprotectedData.Item1[i]) + " " + byteBulkUnprotectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                /**
                * Use protector object to call bulk byte Reprotect API
                */
                Tuple<List<byte[]>, int[]> byteBulkReprotectedData = protector.Reprotect(byteBulkProtectedData.Item1, userName, dataElementName, newDataElementName);
                Console.WriteLine("Reprotected Data is: ");
                for (int i = 0; i < byteBulkReprotectedData.Item1.Count; i++)
                {
                    Console.WriteLine(Encoding.UTF8.GetString(byteBulkReprotectedData.Item1[i]) + " " + byteBulkReprotectedData.Item2[i]);
                }
                Console.WriteLine("\n");

                /**
                * Use protector object to call bulk byte Unprotect API
                */
                Tuple<List<byte[]>, int[]> byteBulkUnprotectReprotectedData = protector.Unprotect(byteBulkReprotectedData.Item1, userName, newDataElementName);
                Console.WriteLine("Unprotected Data is: ");
                for (int i = 0; i < byteBulkUnprotectReprotectedData.Item1.Count; i++)
                {
                    Console.WriteLine(Encoding.UTF8.GetString(byteBulkUnprotectReprotectedData.Item1[i]) + " " + byteBulkUnprotectReprotectedData.Item2[i]);
                }
                Console.WriteLine("\n");
            }
            catch (ProtectorException e)
            {
                Console.WriteLine(e);
            }
        } /* End scope of main function */

    } /* End scope of class */

} /* closure of namespace */

Expected Memory Usage

The process to find the policy size and expected memory usage for different policy sizes used by the .Net application is described in this section.

To find the policy size:

  1. On Insights dashboard, under the Discover section, navigate to the troubleshooting index.
  2. Search using the process.module.keyword: coreprovider filter.
  3. Navigate to the logs with description as Policy successfully loaded. The additional_info.memoryUsed field depicts the policy size.

Memory Usage

Dynamic Memory Usage

The following is the expected memory usage for different policy sizes used by the .Net application.

Policy sizeProcess memory consumption
171 MB223 MB
240 MB292 MB
931 MB982 MB

The process memory increases substantially for a few milliseconds when the application is running in the following cases:

  • The policy is replaced with another policy
  • Changes are made in the current policy

DevOps Memory Usage

If we increase the policy size, the time to load the policy file in the memory increases. For example; for 37 MB, it takes 1 min to load the policy file whereas for 370 MB, it takes approximately an hour to load the policy file.


Last modified : December 18, 2025