Overhead generated by .APPSTATE files on ZCM Client Devices

  • 7007920
  • 16-Feb-2011
  • 31-Dec-2013

Environment

Novell ZENworks 10 Configuration Management
Novell ZENworks 11 Configuration Management

Situation

.APPSTATE files in the %ZENWORKS_HOME%\cache\zmd directory can increase CPU and Memory utilization on a device.

Resolution

Consider the design suggestions listed in Additional Information to keep APPSTATE files small.

To reduce the RAM requirements for large APPSTATE files see Registry key:  HKLM\Software\Novell\ZCM\LoadAppdataIntoMemoryOndemand To delay loading of the action data into the memory to a required point and to reduce the memory footprint for devices with low memory.  For more information see https://www.novell.com/documentation/zenworks11/zen11_sys_registry_keys/data/bvj1efc.html

Additional Information

.APPSTATE files are an XML representation of a bundle. These files are created when the ZCM agent reads bundles associated to a user or device. Each .APPSTATE file that exists on the device, regardless if it is currently associated to the user or device, will result in a additional memory overhead. The larger the .APPSTATE file, the more memory overhead. Creating bundles that result in smaller .APPSTATE files will result in lower overhead on client devices.

ZDM 7 Applications that were migrated to ZCM using the “Individual Actions†option, instead of converting them to MSIs, can result in large .APPSTATE files. A Large number of individual pieces of content in a bundle can also cause large .APPSTATE files.  Actions such as an "Install Directory" option for a directory that contains a large number of files is one example of how this can occur. 

Prior to 11.1:  In lieu of using the "Install Directory" bundle action,  create a self-extracting archive that copies down a single file to the PC and then extracts once copied to the device. 7zip is an FreeWare product that can be used to create self-extracting executable archives. Executing the executable archive with the proper parameters can silently extract the files to the desired location.  

Note: If using ZCM 11.1 or newer, the option "Upload all files within the source directory as a single package"is available and can be used instead of the 7zip option.

For Example:  "My_Install_Files.exe -oc:\MyInstall -r -y" would extract the file My_Install_files.exe to the C:\MyInstall directory without any user interaction. 

To determine the overhead caused by .APPSTATE files, ensure that both the device and user do not directly or indirectly inherit any bundles. Then backup and remove all of the .APPSTATE files from the device and reboot. Manually refresh the agent and using Task Manager, take note of the total amount of memory used by Windows. Reassign the bundles and perform another refresh. Again use Task Manager and take note of the total amount of memory used by Windows.

In addition to memory overhead, large .APPSTATE files can cause some additional Disk/CPU usage during a refresh since the .APPSTATE files for each bundle that is currently assigned to the device or user is fully rebuilt on each refresh.

 
Note: .APPSTATE files are only removed when they are manually deleted from the device.  A device restart is required to reclaim the memory after unused .APPSTATE files are removed.
 
Below is an SQL Query that can be run against your database to generate a list of all bundles, sorted by the number of actions. In general, the size of the .APPSTATE file will correlate to the number of actions. Bundles with a large number of actions tend to be those migrated from ZENworks Desktop management which were initially created using the Snapshot utility and not converted to an MSI during the migration. (Note: This query will not detect bundles that result in large .APPSTATE files due to “Install Directory†actions.)

-----------------------------------------------------------------------------------------------

select b.zuid, b.displayname, count(act.id) from zAction act,
                                                 zBundle b,
                                                 zactionsetobject ao,
                                                 zactionset aset
where ao.zuid = b.zuid
  and aset.actionsetobject = ao.zuid
  and act.actionset = aset.id
group by b.zuid, b.displayname
order by count(act.id) desc;