Java VM Memory Settings

This page discusses the settings that affect the amount of memory usable by StreamBase Studio and StreamBase Server. See also the related page, Garbage Collection Policy Settings.

Default Memory Settings

The Java VM memory settings for StreamBase Studio and StreamBase Server are defined independently in different ways, as described in later sections of this page. The default settings are slightly different between Studio and Server, and differently for 32-bit and 64-bit Server. The settings in this table apply to 32-bit and 64-bit Server running on Windows and UNIX systems:

Java VM Memory Setting Default StreamBase Studio Settings Default 64-bit StreamBase Studio Settings Default 32-bit StreamBase Server Settings Default 64-bit StreamBase Server Settings
-XX:MaxPermSize 256m 512m 128m 256m
-Xms 256m unspecified 256m 1g
-Xmx 768m 2g 512m 2g

In addition, for 64-bit StreamBase Server only, the default JVM settings include -XX:+UseCompressdOops.

In most cases, you only need to be concerned with the JVM settings for StreamBase Server, discussed in the following sections. For editing very large applications in Studio, you might need to separately increase Studio's memory footprint, as described in JVM Memory for StreamBase Studio.

Important

If you make an explicit setting for any of the JVM memory parameters for the Server from the table above, then all of the StreamBase Server default settings are disabled and no longer apply. Thus, if you explicitly set, for example, -Xmx1g, then the default settings for -Xms and -XX:MaxPermSize no longer apply. The simplest solution is to always set all three settings at the same time if you set any one of them.

You can make explicit JVM settings that override the defaults in several ways: in the server configuration file, at the command line with -J options, with the STREAMBASE_JVM_ARGS environment variable, or in custom startup scripts. This note applies to all the ways you might set the JVM memory settings.

Native Code Competition for Memory Resources

Remember that StreamBase Studio running in one Java VM launches StreamBase Server in a separate JVM process with its own memory constraints. Increasing only Studio's memory settings does not help the server load a large application; in fact, it could hamper it.

In a sense, Studio and Server must compete for memory resources on memory-constrained systems. For this reason, only increase Studio's JVM memory settings by the minimum amount that supports acceptable response times for typechecking and editing large applications. For example, on an 8 GB 64-bit system used for editing a large StreamBase application, you might allocate up to 2 GB for Studio, and leave the rest for server launches.

Any memory allocated by native code in the Server startup process is allocated before the JVM starts. Thus, memory allocated by native code Server components is outside the JVM heap and competes for overall memory resources with both Studio and Server.

Native code memory allocations include any memory allocated by the native code portion of the sbd launcher, as well as memory allocated by native code operators and adapters, and by native code DLLs or .so files called by operators or adapters. For example, the native code portion of the sbd launcher allocates some memory for use as a cache for disk-based Query Tables. If you increase the disk-querytable-cache parameter of the <server> element of the server configuration file to a large value, the memory allocated is unavailable for use in the server's JVM heap.

It bears repeating that Studio is designed for authoring, testing, and debugging of applications, but is not designed to host high performance runs of StreamBase Server or for benchmarking of server runs, as discussed in Studio Performance Note.

JVM Memory for StreamBase Server

If you start StreamBase Server without a configuration file, it starts with the internal default settings shown in the table above. You can adjust JVM memory settings for StreamBase Server in the server configuration file. The overall XML syntax for configuration files is described in StreamBase Server Configuration File XML Reference, in the <java-vm> section.

When you generate a default StreamBase Server configuration file in Studio and you opt to include the default contents, or when you generate a default configuration file with sbd –s, the new file contains the following settings for the <java-vm> element:

<java-vm>
  <param name="jvm-args" value="
    -XX:+UseParNewGC
    -XX:+UseConcMarkSweepGC
    -XX:+CMSParallelRemarkEnabled "/>
</java-vm>

The default GC settings are described in Garbage Collection Policy Settings.

Increase the memory available to the next launch of the server by adding entries for the -X settings from the table above. For a medium sized application, use settings like the following:

    -XX:MaxPermSize=256m
    -Xms1g -Xmx2g

For a large application running on a 64-bit host, use settings like these:

    -XX:MaxPermSize=256m
    -Xms2g -Xmx4g

Of course, the system that hosts the server must have enough system memory (including virtual memory) to support the settings you specify. 32-bit Windows systems are limited to an -Xmx setting of about 1400M at most, as described in Optimizing Java Memory on 32-bit Systems. 32-bit Linux systems also have limits, described below.

JVM Memory for StreamBase Studio

In general, StreamBase users do not need to adjust the JVM memory settings for running Studio. When Studio runs or debugs an application on the same machine, it launches StreamBase Server as a separate Java process with its own memory settings.

When Studio launches an application, it honors the <java-vm> settings in a server configuration file named sbd.sbconf that is placed at the root of the application's project folder. (Studio does not use configuration files with other names, or those placed in other folders.) Thus, Studio running with its default memory settings can launch a server process with larger memory settings defined in sbd.sbconf, as long as there is enough system memory (including virtual memory) to support the launch.

An exception exists for those editing very large StreamBase applications with hundreds of components and many sub-modules. In this case, typechecking time and system response time can improve with larger Studio memory settings. StreamBase Systems recommends using 64-bit Studio on 64-bit Windows or 64-bit Linux to edit very large applications.

Adjust Studio's JVM memory settings by setting the STREAMBASE_STUDIO_VMARGS environment variable for the environment in which Studio starts, as described in STREAMBASE_STUDIO_VMARGS. For example, the following setting provides an increase the default values:

STREAMBASE_STUDIO_VMARGS=-Xms512M -Xmx1024M -XX:MaxPermSize=256M

Verify that your machine has enough system memory to support simultaneous editing and launching of large applications. 32-bit Windows and Linux systems require at least 2 GB, with 3 to 4 GB recommended. 64-bit Windows and Linux systems should have 4 GB to take advantage of large JVM settings, with more recommended.

Follow these rules when changing Studio JVM memory settings:

  • You can use the STREAMBASE_STUDIO_VMARGS environment variable to set Java properties for Studio as well as its JVM memory settings, as described in STREAMBASE_STUDIO_VMARGS. Remember to always specify memory settings when you add a property setting to the variable. This may mean re-specifying the default settings.

  • Do not lower the -XX:MaxPermSize setting, which must remain at 256M for Eclipse-based applications.

  • Raise the -Xmx setting incrementally, stopping to test the results. Try adding 256M at a time to the -Xmx value, then run Studio to test its responsiveness:

    -Xms512M
    -Xmx1024M

    Next, try:

    -Xms512M
    -Xmx1280M

    and so on.

  • On 32-bit Windows, there is an absolute upper limit of about 1400M for the -Xmx setting, as discussed below in Optimizing Java Memory on 32-bit Systems.

  • When running 64-bit Studio to edit large applications on a 64-bit system with 8 GB of installed RAM, consider the following settings:

    STREAMBASE_STUDIO_VMARGS=-Xms1024M -Xmx2048M -XX:MaxPermSize=256M
    
  • If you have both 64-bit and 32-bit Studio installed on the same Windows system, remember that they both read the same STREAMBASE_STUDIO_VMARGS environment variable. If you primarily use 64-bit Studio and occasionally run 32-bit Studio for specific purposes, remember to temporarily disable or edit this variable before starting 32-bit Studio.

Diagnostic Settings and Tools

You can configure StreamBase Studio to display its own Java heap memory usage. Run WindowPreferences, select the top-level General page, and select the Show heap status check box. Thereafter, Studio shows current and maximum reserved heap memory usage on the far right of the status bar, in the lower right corner of the Studio window.

To diagnose and troubleshoot memory usage with StreamBase Server, consider adding these additional settings in the jvm-args parameter. These settings cause additional information to be reported to the server console (or to the Console view in Studio) unless specifically overridden.

  • To view information about the Java Just-In-Time (JIT) compiler (HotSpot), try adding:

    -XX:+PrintCompilation
    
  • If the JVM is using an excessive amount of memory, or spending too much time performing garbage collection, try adding this argument to get more specific information:

    -verbose:gc
    

    With this argument, the JVM periodically generates output telling you how large the Java heap size is and how much time is being spent in garbage collection.

  • If the generated code for StreamBase operator execution is not optimal, try adding -Xprof to the set of JVM arguments. Run your application again, and then send the generated information to your StreamBase Systems representative.

You can also use the following tools provided by StreamBase or included as part of its Java installation to inspect memory usage. The tools are listed in order of application-level to Java object-level inspection.

  • Use StreamBase Manager or StreamBase Monitor to see application-level memory use patterns and real-time queue sizes.

  • Use StreamBase profiling to review operator and queue changes over time.

  • Use the Java JConsole utility to see the JVM-level memory use pattern, real-time objects, and threads.

  • Use the Java jmap utility to see what Java objects are on the heap at any point in time. You can also use the Eclipse plug-in MAT (Memory Analyzer Tool) to show the output of jmap in graphical form.

  • Use the Java jstack utility to see what Java threads are working at any point in time.

Optimizing Java Memory on 32-bit Systems

The Oracle Java VM provides the −Xmx switch to control the maximum requested size of the VM memory heap. On 32-bit systems, the maximum allocatable heap is limited because of operating system design constraints.

Java Memory Limits on 32-bit Windows

Experiments with Oracle Java 1.6.0_20 on 32-bit Windows determined that the maximum allocatable Java heap is around 1656 MB, less the size of the PermGen space. Studio requires an −XX:MaxPermSize setting of 256MB, which leaves a practical maximum Java heap of −Xmx1400M for running all Java programs combined, including StreamBase Server, when Studio is running. If you set −XX:MaxPermSize at 128MB for running Server, the practical maximum heap is about -Xmx1528M for running Server by itself.

These numbers are complicated by several factors and may be lower in practice. The complicating factors are:

  • Oracle's JVM heap requires contiguous virtual memory. Thus, a requested heap size of 1 GB requires that a full 1 GB (plus a small amount of overhead) of the virtual address space of a process be contiguously available.

  • The available virtual address space on 32-bit Windows is not the same as the physical memory installed in the system. On 32-bit Windows, the virtual memory space of a process is split in half, with 2 GB reserved for the operating system and 2 GB reserved for the user. The 2 GB of user space is where Windows maps all user images and DLLs, as well as many system DLLs and third party DLLs. Generally, user images are mapped into the lower portion of the 2 GB of user space, while system images are mapped into the upper portion. This leaves a large contiguous hole in the middle of the 2 GB user address space.

    It is common for third-party DLLs to be mapped into the middle of the user process address space without examining the boundaries of the available space. These DLLs can become mapped into the middle of the contiguous address hole described above, effectively breaking it into smaller pieces. Examples of software known to do this are some VPN programs, network discovery agents, and security agents.

These complications can cause StreamBase Server to fail to start when a large JVM heap is requested. The first thing the JVM does on startup is reserve (but not allocate) a contiguous amount of virtual memory equal to the −Xmx value. If there is not enough contiguous memory available, (perhaps because a third party DLL is mapped in the middle), the JVM fails on startup, and shows an error like: Error occurred during initialization of VM. Could not reserve enough space for object heap.

As described in this section, such failures cannot be resolved by adding to physical memory resources. Instead, these failures are the result of fractured virtual memory. For a temporary solution, you can prevent other programs that allocate memory from starting automatically, then reboot Windows. Then try starting StreamBase Server again with a large −Xmx value, up to the absolute limits described above.

For developing and launching very large StreamBase applications, StreamBase Systems recommends developing and testing on a supported 64-bit Windows platform.

Java Memory Limits on 32-bit Linux

The 32-bit Windows constraints do not apply when running 32-bit Linux, but there are still practical limits. Modern Linux kernels take advantage of the Physical Address Extension (PAE) technology provided in recent Intel and AMD CPUs. Linux kernels that support PAE have a way to use installed RAM over 4 GB by swapping memory pages above 4 GB in and out of the addressable 4 GB space. Thus, most 32-bit Linux systems can use all installed physical RAM, and the address space is not divided into 2 GB system and user halves as on Windows.

However, experiments with Oracle Java 1.6.0_20 on 32-bit Linux show that the maximum allocatable Java heap is around 2600 MB. This number is likely to vary widely, depending on your Linux distribution and machine hardware.