Saturday, November 29, 2014

WebLogic Server 12.1.3: weblogic.jar Archive File

Prior to the  release of WebLogic 10.0, the weblogic.jar file could be bundled with a client application to provide WebLogic Server specific value added features, such as:[1]
  • Enhanced JDBC and WLS specific JMX interfaces
  • WLS T3 Client
  • WLS-IIOP Client

Modularity


To boost modularity, WebLogic Server’s file structure have been reorganized for greater flexibility since WLS 10.0. Many WebLogic Server components that were formerly included in the weblogic.jar archive file are now included in separate modules. The weblogic.jar archive now refers to these components in the modules directory from its manifest classpath.

For instance, the weblogic.jar in WLS 12.1.3 includes relative manifest classpath references to:
  • $WL_HOME/modules
  • $(dirname $WL_HOME)/oracle_common/modules
directories.

Because of this, weblogic.jar can no longer simply be moved to any new location without complications.

META-INF/MANIFEST.MF


As a consequence of the weblogic.jar reorganization, weblogic.jar is simply a container for the manifest file (i..e, META-INF/MENIFEST.MF).

Here is the contents of manifest file in weblogic.jar of WLS 12.1.3:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.2
Created-By: 1.7.0_15-b33 (Oracle Corporation)
Main-Class: weblogic.Server
Implementation-Vendor: BEA Systems
Implementation-Title: WebLogic Server 12.1.3.0.0  Fri Dec 27 03:55:01
 PST 2013 1570920
Implementation-Version: 12.1.3.0.0
Class-Path: weblogic-classes.jar ../../../oracle_common/modules/featur
 es/com.oracle.db.jdbc7-no-dms.jar ../../modules/features/weblogic.ser
 ver.merged.jar ../../modules/features/weblogic.server.merge.modules_1
 2.1.3.0.jar ../../../oracle_common/common/lib/config-launch.jar schem
 a/weblogic-domain-binding.jar schema/weblogic-domain-binding-compatib
 ility.jar schema/diagnostics-binding.jar schema/diagnostics-image-bin
 ding.jar aqapi.jar ../../../oracle_common/modules/mysql-connector-jav
 a-commercial-5.1.22/mysql-connector-java-commercial-5.1.22-bin.jar cr
 yptoj.jar  ../../../oracle_common/modules/datadirect/wlsqlserver.jar
 ../../../oracle_common/modules/datadirect/wldb2.jar ../../../oracle_c
 ommon/modules/datadirect/wlsybase.jar ../../../oracle_common/modules/
 datadirect/wlinformix.jar ../../../oracle_common/modules/datadirect/f
 mwgenerictoken.jar osgi.jar wlw-langx.jar jcom.jar weblogic-L10N.jar
 wljaccutil.jar   ../../modules/features/weblogic.server.modules_12.1.
 3.0.jar

Thursday, November 27, 2014

WebLogic: Important Deployment Concepts

WebLogic Server implements the Java EE 5 specification. Java EE 5 includes a deployment specification, JSR-88,[1] that describes a standard API used by deployment tools and application server providers to configure and deploy applications to an application server.

Although the Java EE 5 deployment API provides a simple, standardized way to configure applications and modules for use with a Java EE 5-compliant application server, the specification does not address many deployment features that were available in previous WebLogic Server releases. For this reason, WebLogic Server provides important extensions to the Java EE 5 deployment API specification to support capabilities described in [2].

In this article, we will discuss some important concepts for understanding the deployment process in WebLogic Server.


Deployment Tools



The term application deployment refers to the process of making an application or module available for processing client requests in a WebLogic Server domain.  You have several options to deploy a web application onto WebLogic Server:
  • weblogic.Deployer
    • A packaged deployment tool which provides deployment services for WebLogic Server. 
    • Any deployment operation that can be implemented using the WebLogic Deployment API[19] is implemented, either in part or in full, by weblogic.Deployer.
    • weblogic.Deployer is the recommended deployment tool for the WebLogic Server environment. 
  • WLDeploy
  • WLST[4,5,20]
    • WLST functionality includes the capabilities of the following WebLogic Server command-line utilities:
      • weblogic.Deployer
      • WLDeploy
  • JSR-88 API for deployment
    • WebLogic Deployment API,[19] which implements and extends the Java EE Deployment API specification (JSR-88)
    • The WebLogic Deployment API[19] classes and interfaces extend and implement the Java EE Deployment API specification (JSR-88) interfaces, which are described in the javax.enterprise.deploy sub-packages.[6]
  • JMX Deployment API[7]
    • Supports all of the common functionality available in the Java EE Deployment API specification (JSR-88). 
    • You can use the JMX API as an alternative to JSR-88 to perform deployment tasks on specified target servers
  • WLS console (through JSR-88 API)[8]
  • FMWC (through JSR-88 API and JMX Deployment API)[9]


Deployment Concepts


To help you understand the deployment process in WebLogic Server, we have listed the most important concepts below:
  • Deployable objects (or artifacts)
    • Which can be deployed on a weblogic domain
      • EJBs
      • Modules
        • Supported module types include:[11,12]
          • JMS, JDBC, Interception, Config, and WLDF[10]
      • Web Services
      • Applications[13]
    • Physical package types:
      •  EARs, standalone J2EE and non-J2EE modules
  • Deployment operations (or tasks)
    • Such as distributing, starting, stopping, deploying, redeploying, undeploying, etc.
      • deploying
        • if successful, an AppDeploymentMBean[14] for the application will be created 
  • Deployment targets
    • Target types available to WebLogic Server include:
      • Cluster
      • JMS Server
      • SAF Agent
      • Server
      • Virtual host 
  • Deployment order
    • An integer value that indicates when this artifact is deployed, relative to other deployable artifacts on a server, during startup.
    • Artifacts with lower values are deployed before those with higher values.
  • Deployment plan
    • You can use either Weblogic Console or weblogic.PlanGenerator to export portions of a WebLogic Server deployment configuration into a deployment plan file.[16,17]
    • Describes the application structure, identifies all deployment descriptors, and exports a subset of the application's configurable properties.  For example, it includes:
      • Resource dependencies
      • Resource declarations
      • Non-resource oriented configurable properties
      • Properties that may be changed in a running application, etc
    • A deployment plan is an XML document used to define an application's deployment configuration for a specific WebLogic Server environment, such as development, test, or production. 
    • A deployment plan resides outside of an application's archive file and contains deployment properties that override an application's existing Java Enterprise Edition and WebLogic Server deployment descriptors. 
    • Use deployment plans to easily change an application's WebLogic Server configuration for a specific environment, without modifying existing deployment descriptors.
  • Deployment configuration
    • Refers to the process of preparing an application or deployable resource for deployment to a WebLogic Server instance.
    • Modification of individual WebLogic Server configuration values based on user inputs and the selected WebLogic Server targets
  • Deployment staging
    • The staging mode of an application or deployment plan can be provided to affect its deployment behavior.
      • An application's deployment plan can be staged independently of the application archive, allowing you to stage a deployment plan when the application is not staged.
      • If you do not specify a staging mode, the deployment plan uses the value specified for application staging as the default.
    • Staging mode includes:
      • STAGE—Application files (or deployment plans) are copied to target servers
      • NO_STAGE—Application files (or deployment plans) are not copied to target servers
      • EXTERNAL_STAGE—Application files (or deployment plans) are copied manually to target servers

"Install Root" Abstraction


The SessionHelper[18] in WebLogic Deployment API[19] views an application and deployment plan artifacts using an "install root" abstraction, which ideally is the actual organization of the application. The install root appears as follows:

install-root (eg myapp) 
-- app 
----- archive (eg myapp.ear) 
-- plan
----- deployment plan (eg plan.xml) 
----- external descriptors (eg META-INF/weblogic-application.xml...) 

Optionally, you may consider using this layout to organize your applications and deployment plans.

References

  1. JSR 88: JavaTM EE Application Deployment
  2. WebLogic Server Deployment Features
  3. Understanding the WebLogic Deployment API (WebLogic 12.1.2)
  4. WLST FAQs
  5. WLST Command and Variable Reference
  6. Java EE 5 API Summary
  7. The JMX API for Deployment Operations
  8. Administration Console Online Help
  9. Using Fusion Middleware Control to Manage WebLogic Server
  10. The Configuration File in WebLogic Server Domain — config.xml (Xml and More)
  11. Module Types
  12. Example Module Deployment
  13. Oracle® Fusion Middleware Deploying Applications to Oracle WebLogic Server
  14. Interface AppDeploymentMBean
  15. MBean Reference for Oracle WebLogic Server
  16. Create a deployment plan using Administration Console
  17. Oracle WebLogic Server 12c: Creating and Using a Deployment Plan
  18. SessionHelper
  19. WebLogic Deployment API
  20. WLST: deploy command (WLS 12.1.2)
  21. Pack and Unpack Commands
    • Provide a simple, one-step method for creating WebLogic domains and templates from the command line.
    • You cannot, however, use these commands to customize the contents of your WebLogic domain or template in the same way as with the other tools (i.e., Configuration Wizard or WLST).
  22. Deployment Tools for Developers (WLS 12.1.1)

Sunday, November 23, 2014

G1 GC: Humongous Objects and Humongous Allocations

For Garbage First Garbage Collector (G1 GC), any object that is more than half a region size is considered a Humongous Object.   A humongous object is directly allocated into Humongous Regions.[1]

In this article, we will discuss the following topics:
  • Humongous regions and humongous allocations
  • How humongous allocations impact G1's performance?
  • How to detect humongous allocations?
    • Basic Investigation
    • Advanced Investigation

Humongous Regions and Humongous Allocations


A humongous object is allocated directly in the humongous regions. These humongous regions are a contiguous set of regions. StartsHumongous marks the start of the contiguous set and ContinuesHumongous marks the continuation of the set.

Before allocating any humongous region, the marking threshold is checked, initiating a concurrent cycle, if necessary. Dead humongous objects are freed at the end of the marking cycle during the cleanup phase also during a full garbage collection cycle (but, a new implementation has changed this; see the next section).

Since each individual set of StartsHumongous and ContinuesHumongous regions contains just one humongous object, the space between the end of the humongous object and the end of the last region spanned by the object is unused. For objects that are just slightly larger than a multiple of the heap region size, this unused space can cause the heap to become fragmented.

How Humongous Allocations Impact G1's Performance?


In the old implementation, humongous objects are not released until after a full concurrent marking cycle.[4]  This is far from ideal for many transaction-based enterprise applications that create short-lived (i.e., in the transaction scope) humongous objects such as ResultSet(s) generated from JDBC queries.  This results in the heap filling up relatively quickly and leads to unnecessary marking cycles to reclaim them.

A new implementation since:
java version "1.8.0_40-ea"
Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b05, mixed mode)
handles humongous regions differently and can reclaim them earlier if they are short-lived (see [4] for details).

For investigating humongous allocations in G1, you should begin with the following minimal set of VM options:
  • -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintReferenceGC (-XX:+UseG1GC)

Basic Humongous Allocation Investigation


For basic humongous allocations investigation, you simply add a new option:
  • -XX:+PrintAdaptiveSizePolicy
This option will print out something like below:
12025.832: [G1Ergonomics (Concurrent Cycles) request concurrent cycle initiation, reason: occupancy higher than threshold, occupancy: 3660578816 bytes, allocation request: 1048592 bytes, threshold: 3650722120 bytes (85.00 %), source: concurrent humongous allocation]
From the above, we saw a humongous allocation is initiated with a request size of 1048592 bytes. Note that our region size is 1MBytes in this test. So, the request object is considered as humongous (i.e., 1048592 Bytes > half of 1 MBytes).

In the output, you can also find the following entries:
      [Humongous Reclaim: 0.0 ms]
         [Humongous Total: 54]
         [Humongous Candidate: 0]
         [Humongous Reclaimed: 0]
This shows that there are 54 humongous regions found in this GC event.   Also, none of them were reclaimed in this GC event. The reason is that the current algorithm is relatively conservative and it skips humongous objects for reclamation if there are sparse references into them.  In the case that those references belongs to sparse table entries, G1 may improve the reclamation rate by discovering if they are actually not referenced at all after iterating the table.  A performance enhancement is pending for this effort now.[5]

Advanced Humongous Allocation Investigation


To further investigate humongous allocation in more details, you can add:
-XX:+PrintAdaptiveSizePolicy -XX:+UnlockExperimentalVMOptions -XX:+G1ReclaimDeadHumongousObjectsAtYoungGC -XX:G1LogLevel=finest -XX:+G1TraceReclaimDeadHumongousObjectsAtYoungGC
Note that the following VM options are experimental:
  • G1TraceReclaimDeadHumongousObjectsAtYoungGC[4]
  • G1ReclaimDeadHumongousObjectsAtYoungGC[3]
  • G1LogLevel (i.e., [fine|finer|finest])
So, that's why we added the unlock option;
-XX:+UnlockExperimentalVMOptions
With extra printing options, you will find detailed description of humongous allocations as shown below:
3708.669: [SoftReference, 0 refs, 0.0000340 secs]3708.669: [WeakReference, 1023 refs, 0.0001790 secs]3708.669: [FinalReference, 295 refs, 0.0007020 secs]3708.670: [PhantomReference, 0 refs, 0.0000060 secs]3708.670: [JNI Weak Reference, 0.0000140 secs]Live humongous 1 region 9 size 65538 with remset 1 code roots 0 is marked 0 live-other 0 obj array 0

Live humongous 1 region 10 size 88066 with remset 1 code roots 0 is marked 0 live-other 0 obj array 0
Live humongous 1 region 15 size 262146 with remset 1 code roots 0 is marked 0 live-other 0 obj array 1
...
Finally, you can also use Java Flight Recorder (JFR) and Java Mission Control (JMC) to get information about humongous objects by showing their allocation sources with stack traces.[7]

References

  1. Garbage First Garbage Collector Tuning
  2. G1GC: Migration to, Expectations and Advanced Tuning
  3. Thread local allocation buffers (TLAB's)
  4. Early reclamation of large objects in G1
    • Introduced since 8u40 b02 and 8u45
    • Was not back ported to 8u20
  5. Early reclaim of large objects that are referenced by a few objects
  6. G1TraceReclaimDeadHumongousObjectsAtYoungGC
    • JDK-8058801
      • Prints information about live and dead humongous objects
        • (Before bug fix) prints that information when there is at least one humongous candidate.
        • (After bug fix) prints that information even when there is no humongous candidates; it also prints humongous object size in the output
  7. Java Mission Control (JMC) and Java Flight Recorder (JFR)
  8. Garbage-First Garbage Collector (JDK 8 HotSpot Virtual Machine Garbage Collection Tuning Guide)
  9. Other JDK 8 articles on Xml and More

Saturday, November 22, 2014

Java SecurityManager: "java.security" and "java.policy" Files

In many cases, where the threat model does not include malicious code being run in the JVM, the Java Security Manager[1] is unnecessary. However, when untrusted third-parties use WebLogic Server[2] and untrusted classes are being run, the Java Security Manager may be useful.

In this article, we will discuss the following topics:
  1. What is Java Security Manager?
  2. What is "java.security" file?
  3. What is "java.policy" file?

Java Security Manager


The JVM has security mechanisms built into it that allow you to define restrictions to code through Java security policy files (i.e., java.policy file). The Java Security Manager uses these policies to enforce a set of permissions granted to classes. The permissions allow specified classes running in that instance of the JVM to allow or not allow certain runtime operations.

Therefore Java Security Manager can be used with WebLogic Server to provide additional protection for resources running in a Java Virtual Machine (JVM).[1] However, using a Java Security Manager is an optional security step.

To use the Java Security Manager with WebLogic Server, just specify:
-Djava.security.manager -Djava.security.policy=${WL_HOME}/server/lib/weblogic.policy
arguments when starting WebLogic Server. The -Djava.security.policy argument specifies a filename (using a relative or fully-qualified pathname) that contains Java 2 security policies.[5] If weblogic.policy file is provided, then the specified policy file will be loaded in addition to all the policy files that are specified in the security properties file (see "java.policy" section).  If you instead type the following command options, using a double equals, then just the specified policy file will be used; all others will be ignored:
-Djava.security.manager -Djava.security.policy==${WL_HOME}/server/lib/weblogic.policy

java.security


A security model can be as simple as the one supported in Linux or Windows file system—file permissions are granted to principals based on user IDs. Or it can be as sophisticated as the one implemented in Adobe Flash Player (see [6] for details). Java Security Manager supports a security model sits in between the two in terms of complexity and capability.

Sometimes a Java application (like, say, a Web browser) needs to run untrusted code within itself. In this case, Java system libraries need some way of distinguishing between calls originating in untrusted code and calls originating from the trusted application itself. Clearly, the calls originating in untrusted code need to be restricted to prevent hostile activities. By contrast, calls originating in the application itself should be allowed to proceed (as long as they follow any security rules that the operating system mandates).

Security is all about separation by creating protection domains. Access control in Java Security Manager is enforced with the help of:[10]
  • Executable Code Identity
    • Decisions are based on the identity of the executable code
      • AccessController in java.security package consults policy and uses stack inspection (see below) to decide whether to allow or disallow a call.
    • Executable code is categorized based on its URL of origin and the private keys used to sign the code:
      • Code source
        • Note that permission objects are associated with each code source
      • Signature
    • Trusted code vs untrusted code
  • Protected System Resource
    • File access
    • Network access (via sockets)
    • Listening ports, etc.
  • Permission (or privilege)
    • Permission is configure by:
      • Grant Target
        • Such as the name of a file
      • Grant Action
        • Such as "read" action on a file
    • Collection of Permissions
      • Homogeneous vs heterogeneous
  • Logical groupings
    • Separating groups from each other and granting groups particular permissions.

Stack Inspection

Java implements its security system by allowing security-checking code to examine the runtime stack for frames executing untrusted code. This is called stack inspection.[7] Java Security Manager inspects the stack in order to make access control decisions.

Each thread of execution has its own runtime stack. The stack grows and shrinks during typical program operation. Each stack frame includes both a method call and a trust label (T for trusted, U for untrusted).

Security Properties File Location

The security properties file is located in the file named

java.home/lib/security/java.security (Solaris/Linux/Mac OS X)
java.home\lib\security\java.security (Windows)

java.policy


Java security can be dictated by security policies. A policy file can be composed via a simple text editor, or via the graphical Policy Tool utility.[8] There is by default a single system-wide policy file, and a single (optional) user policy file. Policy can be set by the user (usually a bad idea) or by the system administrator, and is represented in the class java.security.Policy.

The configuration file(s) specify what permissions are allowed for code from a specified code source, and executed by a specified principal. Each configuration file must be encoded in UTF-8.[4]

Policy File Location

Policy file locations are specified in the security properties file (i.e., java.security).  For example, the default system and user policy files are defined using URL specification in the security properties file as:

policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy


System Policy File

The system policy file is meant to grant system-wide code permissions. It is by default located at

java.home/lib/security/java.policy (Solaris/Linux/Mac OS X) 
java.home\lib\security\java.policy (Windows)

The java.policy file installed with the JDK grants all permissions to standard extensions, allows anyone to listen on un-privileged ports, and allows any code to read certain "standard" properties that are not security-sensitive, such as the "os.name" and "file.separator" properties.

Executable code is categorized based on its URL of origin and the private keys used to sign the code. The security policy maps a set of access permissions to code characterized by particular origin/signature information. Protection domains can be created on demand and are tied to code with particular CodeBase and SignedBy properties.

Code can be signed with multiple keys and can potentially match multiple policy entries. In this case, permissions are granted in an additive fashion

References



Tuesday, November 18, 2014

WLST: Offline and Online Modes

In this article, we will cover the following topics:
  • How to invoke WLST?
  • Offline and Online WLST
  • How to switch from Offline to Online mode?

How to invoke WLST?


In a Windows environment, you can start WLST from the Start program by simply selecting:
Start | Programs | Oracle | Oracle Home | WebLogic Server 12c | Tools | WebLogic Scripting Tool
You can also invoke WLST from the command line by using:[1]
  • The java weblogic.WLST command or 
  • The command script wlst.cmd (wlst.sh in UNIX)

java weblogic.WLST Command

D:\>cd Oracle\wls1036tx\user_projects\domains\base1_domain\bin
D:\Oracle\wls1036tx\user_projects\domains\base1_domain\bin>setDomainEnv.cmd
D:\Oracle\wls1036tx\user_projects\domains\base1_domain>java weblogic.WLST

Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands

wls:/offline>

Command Script wlst.cmd

D:\>cd Oracle\wls1036tx\oracle_common\common\bin
D:\Oracle\wls1036tx\user_projects\domains\base1_domain\bin> wlst.comd
CLASSPATH=C:\Oracle\MIDDLE~1\patch_wls1211\profiles\default\sys_manifest_classpath\weblogic_patch.jar;...

Initializing WebLogic Scripting tool (WLST)...
Type help() for help on available commands

wls:/offline>

Note that you use the wlst.cmd script from the ORACLE_HOME\oracle_common\common\bin directory and not a directory specific to any particular WebLogic Server domain.[1]

Offline and Online WLST


As shown above, both WLST invocations bring you to the offline mode.  In the next section, we will show how to switch from offline to online mode and vice versa.  To begin with, here are what offline and online mode can and can't do:[5]


WLST Offline
WLST Online
Can Do
  • Create/modify domain templates
  • Create domains
  • Extend an existing domains by access and modify the configuration for an offline domain
  • Change configuration when servers are in RUNNING state
  • View runtime data for monitoring various runtime MBeans performances
  • Deploy applications targeting to Servers or clusters
  • Start and stop servers or cluster members.
Can't Do
  • View runtime performance data
  • Modify security data
  • Create a new domain (must be offline mode)
    • You can only update an existing domain configuration.


Online Mode

In online mode, WLST needs to connect to an active Admin or Managed Server.  The WLST online commands are analogous to the Administration Console changes after connecting to Admin Server.  WLST in online mode acts as a Java Management Extensions (JMX) client that manages the domain's resources by modifying the server's in-memory runtime Management Beans (MBeans). Thus, WLST offers you all the domain management configuration capabilities as the Administration Console.

Offline Mode

In offline mode, WLST helps you extend a domain, create domain templates, and create domains with those templates. Since you aren't connected to an active Admin Server, you won't be able to modify domain configuration in offline mode.

The WLST offline configuration commands are analogous to the Configuration Wizard. You just need to know the navigation on the configuration MBean trees, modify the MBean attribute values. Internally WLST offline commands work on WebLogic domain Configuration Framework, which Configuration Wizard also uses.  Using either tool, modified configuration data are persisted consistently in  the domain’s config directory or in a domain template JAR.

You can list a summary of all online and offline commands from the command-line using the following commands, respectively:[3,4]
help("online")
help("offline")

How to Switch from Offline to Online mode?


You can switch from offline to online mode and vice versa by using connect() and disconnect() commands. When you use connect() command at offline it will transfer your prompt to ServerConfig that indicates online command mode.  The following example shows you how:
wls:/offline> connect('weblogic', 'welcome1', 't3://myserver:7001')

Connecting to t3://myserver:7001 with userid weblogic ...
Successfully connected to Admin Server "myserver" that belongs to domain "mydomain".

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

wls:/mydomain/serverConfig> disconnect()

Disconnected from weblogic server: myserver

In order to...
Use this command...
To...
Use with WLST...
Connect to and disconnect from a WebLogic Server instance
Connect WLST to a WebLogic Server instance.
Online or Offline
Disconnect WLST from a WebLogic Server instance.
Online


References

Saturday, November 8, 2014

HotSpot: GC Worker Threads Used in CMS, Parallel, and G1 GC

As discussed in [1], the Java HotSpot virtual machine includes five garbage collectors (or GC):
  • Serial Collector
  • Parallel Collector (or throughput collector)
  • Parallel Compacting Collector
  • Concurrent Mark-Sweep (CMS) Collector
  • Generation First (G1) Garbage Collector
Also, in [2], we have shown how to find the default HotSpot JVM values.  Some VM options are set from command line and some are set by GC's ergonomics.  However, all VM options are printed when you execute:
  • -XX:+PrintFlagsFinal
Using G1 GC as an example, it uses SurvivorRatio, but not InitialSurvivorRatio, MinSurvivorRatio, or TargetSurvivorRatio.  In this article, we will show you one way to tell which VM option is used by which GC.

GC Threads


In [3], we have discussed the difference between Parallel Collectors and Concurrent Collectors.

Parallel collectors require stop-the-world pause for the whole duration of major collection phases (mark or sweep), but employ all available cores to compress pause time. Parallel collectors usually have better throughput, but they are not a good fit for pause critical applications. 
Concurrent collectors try to do most work concurrently (though they also do it in parallel on multi-core systems), stopping the application only for short duration. Note that the concurrent collection algorithm in JRockit is fairly different from both HotSpot's concurrent collectors (CMS and G1).

There are three kinds of GC threads utilized in HotSpot for CMS, Parallel, and G1 garbage collectors:
  • ParallelGCThreads
  • ConcGCThreads 
  • G1ConcRefinementThreads
When you use PrintFlagsFinal to print out all JVM flags for CMS, Parallel or G1 GC.  The results are as follows:

CMS
    uintx ParallelGCThreads           = 23     {product}
    uintx ConcGCThreads               = 6      {product}
    uintx G1ConcRefinementThreads     = 0      {product}
Parallel GC     uintx ParallelGCThreads           = 23     {product}     uintx ConcGCThreads               = 0      {product}     uintx G1ConcRefinementThreads     = 0      {product}
G1 GC
    uintx ParallelGCThreads           = 23     {product}
    uintx ConcGCThreads               = 6      {product}
    uintx G1ConcRefinementThreads     = 23     {product}

Based on JDK-8047976,[4] it says that GC's normally don't update flags they do not use.  That's why we see "0" in some of the printouts.  To summarize, here are the GC worker threads used in CMS, Parallel, and G1 garbage collectors:

Garbage Collector
Worker Threads Used
CMS
ParallelGCThreads
ConcGCThreads
Parallel
ParallelGCThreads
G1
ParallelGCThreads
ConcGCThreads
G1ConcRefinementThreads

Note that the above description is valid for the following JVM version or later ones:
java version "1.8.0_40-ea"
Java(TM) SE Runtime Environment (build 1.8.0_40-ea-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b16, mixed mode)
Because JDK-8047976 bug,[4] the behavior is different if you use earlier versions.

References

  1. HotSpot VM Performance Tuning Tips (Xml and More)
  2. What Are the Default HotSpot JVM Values? (Xml and More)
  3. JRockit: Parallel vs Concurrent Collectors (Xml and More)
  4. Ergonomics for GC thread counts should update the flags
  5. Tuning that was great in old JRockit versions might not be so good anymore
    • Trying to bring over each and every tuning option from a JR configuration to an HS one is probably a bad idea.
    • Even when moving between major versions of the same JVM, we usually recommend going back to the default (just pick a collector and heap size) and then redoing any tuning work from scratch (if even necessary).

Sunday, November 2, 2014

G1 GC: What Is "to-space exhausted" in GC Log?

As shown in [1], you can enable basic garbage collection (GC) event printing using two options:
  • -XX:+PrintGCTimeStamps (or -XX:+PrintGCDateStamps) 
  • -XX:+PrintGCDetails
These additional printing incurs minimal overhead while provide useful information for understanding the healthiness of your running garbage collector (e.g., Generation First GC).

In this article, we will discuss the significance of to-space exhausted events in your GC logs.

What Is "to-space exhausted"?


When you see to-space exhausted messages in GC logs, it means that G1 does not have enough memory for either survived or tenured objects, or for both, and the Java heap cannot be further expanded since it is already at its max.[5]  This event only happens in mixed GC 's when G1 tries to copy live objects from the source space to the destination space.  Note that, in G1, it avoids heap fragmentation by compaction (i.e., done when objects are copied from source region to destination region).

Example message:

5843.494: [GC pause (G1 Evacuation Pause) (mixed)... (to-space exhausted), 0.1145790 secs]

When that happens, GC pause time will be longer (i.e., since both RSet and CSet[5] need to be re-generated) and sometimes it may require a Full GC to resolve the issue. 

A Case Study of "to-space exhausted" Events


Using a benchmark with large live data size,[3] a "to-space exhausted" event can be triggered if there is not enough breathing room for shuffling live data objects in the Java heap.  For example, we have a test case which its live data set occupies 68% of the Java heap at run time.  In a 4-hour run, we have seen the following sequence of events:

5843.494: [GC pause (G1 Evacuation Pause) (mixed)... (to-space exhausted), 0.1145790 secs]
5848.831: [GC pause (G1 Evacuation Pause) (mixed)... (to-space exhausted), 0.0847160 secs]
5856.640: [GC pause (G1 Evacuation Pause) (mixed)... 0.0864060 secs]
5866.182: [GC pause (G1 Evacuation Pause) (mixed)... 0.0821220 secs]
5875.550: [GC pause (G1 Evacuation Pause) (mixed)... 0.0549090 secs]
5882.353: [GC pause (G1 Evacuation Pause) (mixed)... 0.0827630 secs]
5896.331: [GC pause (G1 Evacuation Pause) (mixed)... 0.0632660 secs]
5901.966: [GC pause (G1 Evacuation Pause) (mixed)... 0.5356580 secs]
5902.813: [GC pause (G1 Evacuation Pause) (mixed)... (to-space exhausted), 1.3480320 secs]
5904.162: [Full GC (Allocation Failure) ... 5.0413590 secs]

A series of "to-space exhausted" events eventually led to a Full GC.  As discussed in [4], adding -Xmn400m on the command line to the same test case further add insult to injury—instead of seeing 3 "to-space exhausted" events, now we saw 20 of them.  This is due to we have further cut down the breathing room for G1.



How to Deal with "to-space exhausted" Events?


"to-space exhausted" events happen when G1 runs out of space (either survivor space or old space; see diagram above) to copy live objects to.  When it happens, sometimes G1's ergonomics can get by the issue by dynamically re-sizing heap regions.  If not, it eventually leads to a Full GC event.

When "to-space exhausted" events happen, it could mean you have a very tight heap allocated for your application.  The easiest approach to resolve this is increasing your heap size if it's possible. Alternatively, sometimes it's possible to tune G1's mixed GC to get by (see [4]). As shown in the above section, we have a high live data occupancy (i.e., 68%) in Java heap.  However, after tuning mixed GC, we can get by with a couple of Full GC's in a 4-hour run, which yields satisfactory result.

Note that mixed GC can clean up both young and old regions. If it does not take an old region, it would be a young(-only) GC. G1's mixed GC's are meant as a replacement for Full GC's. Instead of doing all the work at once, the idea is to achieve the same task in steps. Each small steps in mixed GC is smaller than a Full GC. Because G1 does not intend to reclaim all garbage as in a Full GC event, mixed GC uses less time.  However, Full GC is a compaction event which it can walk around "to-space exhausted" issue without needing extra space.

Acknowledgement


Some writings here are based on the feedback from Thomas Schatzl and Yu Zhang. However, the author would assume the full responsibility for the content himself.

References

  1. g1gc logs - basic - how to print and how to understand
  2. g1gc logs - Ergonomics -how to print and how to understand
  3. JRockit: How to Estimate the Size of Live Data Set
  4. JDK 8: Is Tuning MaxNewSize in G1 GC a Good Idea?
  5. Garbage First Garbage Collector Tuning
    • Note that "to-space overflow" message was removed and only "to-space exhausted" remains.
    • RSet (Remembered Set)—Tracks object references into a given region. There is one RSet per region in the heap. The RSet enables the parallel and independent collection of a region. The overall footprint impact of RSets is less than 5%.
    • CSet (Collection Set)—Are the set of regions that will be collected in a GC. All live data in a CSet is evacuated (copied/moved) during a GC. Sets of regions can be Eden, survivor, and/or old generation. CSets have a less than 1% impact on the size of the JVM. 
  6. HotSpot Virtual Machine Garbage Collection Tuning Guide
  7. Garbage-First Garbage Collector Tuning
  8. Getting Started with the G1 Garbage Collector
  9. Garbage-First Garbage Collector (JDK 8 HotSpot Virtual Machine Garbage Collection Tuning Guide)
  10. Other JDK 8 articles on Xml and More