Note that only the first partition (i.e., P_0) was specified at beginning and that interval's high value (see below for explanation) is "2012-12-23 00:00:00". It also specifies that above the transition point of December 23, 2012, partitions will be created with a width of one day.

Query by Partition Name

The normal way to reference a specific partition is to use the partition (partition_name) in the query. For example, we have found 13187 rows in our newly created partition (i.e., SYS_P23979).

Partitions Created Automatically

Inserting a row that has a date later than December 23, 2012 (i.e., our initial partition's high value) would raise an error with normal range partitioning. However, with interval partitioning, Oracle 11g determines the high value of the defined range partitions, called the transition point, and creates new partitions for data that is beyond that high value.

If you have a benchmark that will be run repeatedly for a long time, controlling the growth of your database is important. To find out how many partitions were added in PS_TXN table, you can do the following:

In our latest run, a system generated partition named SYS_P23979 was added and you can find it at the last row above. Totally, there are 215 partitions found. In other words, 214 new partitions were added since the creation of PS_TXN table.

Conclusions

Oracle Fusion Applications use the PS_TXN table to store the intermediate processing state. When there are many concurrent users, this table receives a high number of inserts and could suffer from contention issues.

Saturday, January 25, 2014

In [1], we have shown how to use OQL to query String instances starting with a specified substring (i.e., our objects of interest) from a heap dump.[7,8] To determine who is creating these objects, or find out what the purpose of some structures are, an object's incoming and outgoing references become handy.

In this article, we will examine the following topics:

What are incoming references or outgoing references of an object?

Then look at two topics related to incoming references:

Path To GC Roots

Immediate Dominators

Outgoing References

Using the following OQL statement, we have identified total 7 entries (see Figure above) as our objects of interest:

SELECT * FROM java.lang.String WHERE toString().startsWith("http://xmlns.oracle.com/apps/fnd/applcore/log/service/types")

After expanding the first entry, it shows two outgoing references:

a reference to the Class instance for the String object

a reference to an array of char values

Outgoing References show the actual contents of the instances, helping to find out their purpose. In our String instance, it holds two references. The memory overhead of this String instance is shown in two values: [3]

Shallow Heap

Retained Heap

These sizes of String instances depends on the internal implementation of the JVM. Read [2,4] for more details.

Incoming References

To get incoming references of the first entry, choose List Objects with Incoming References from the context menu.

Now a tree structure is displayed, showing all instances with all incoming references (note the different icon highlighted in red). These references have kept the object alive and prevented it from being garbage collected.

Immediate Dominators

Similarly, from the context menu, you can display immediate dominators of the first entry (see Figure below). An Object X is said to dominate an Object Y if every path from the GC Root to Y must pass through X. So, immediate dominators is a very effective way to find out who is keeping a set of objects alive. For example, the immediate dominators of our first entry (note that we have used "java.*|com\.sun\..*" as our filter) is:

oracle.j2ee.ws.server.deployment.WebServiceEndpoint

Path To GC Roots

From context menu, you can also show "Path to GC Roots" of the first entry (see Figure below). Path to GC Roots shows the path to GC roots which should be found for a given object. As you can expect, its immediate dominators must also be on this path. Note that, when you display Path to GC Roots, you can specify which fields of certain classes to be ignored when finding paths. For example, we have specified that paths through Weak or Soft Reference referents to be excluded.

Live Data Set

Now we know

oracle.j2ee.ws.server.deployment.WebServiceEndpoint

is keeping our String instance alive. Instead of viewing Path to GC Roots, it is easier to see it the other way around. So, we have chosen to display the outgoing references of WebServiceEndpoint instance (see Figure below). As you can see, our String instance is displayed as the leaf node of the tree structure.

select * from java.lang.String where toString().startsWith("http://xmlns.oracle.com/bpel")

to query String objects with a certain prefix (i.e., "http://xmlns.oracle.com/bpel") and calculate the total size of retained heap associated with the interested objects.

Shallow vs. Retained Heap

As shown in the Figure, two sizes of an object are displayed in the Result area:

Shallow heap

Retained heap

Generally speaking, shallowheap of an object is its size in the heap and retained size of the same object is the amount of heap memory that will be freed when the object is garbage collected. In other words, retained heap of object X is the sum of shallow sizes of all objects in the retained set of X, the set of objects which would be removed by Garbage Collector when X is garbage collected.

As said in [6], while Shallow Heap can be interesting, the more useful metric is the Retained Heap. For example, you can benchmark retained sizes of interested objects before and after your code optimizations. Below, we will show how to compute the total retained size of our interested objects.

Exporting to CSV...

Analyzed data can be exported from the heap editor by:[5]

Using the toolbar export menu (you can choose between export to HTML, CSV, and TXT)

Let's say we have exported it to a CSV file named RetainedHeap.txt.

Importing CSV File into Excel

You can use Java code to parse the CSV file and compute the retained heap of interested objects. An alternative way is using Excel, which is demonstrated here.

First, you open RetainedHeap.txt and specify both comma and space as the delimiters of fields.

Then, select all "Retained Heap" fields (shown in red) and compute the Sum as shown below:

Finding Responsible Objects

To investigate your potential memory leaks, it will be important to answer the following question:

Who has kept these objects alive?

To answer that, you can use Immediate Dominators (an Object X is said to dominate an Object Y if every path from the Root to Y must pass through X) from the context menu. This query finds and aggregates all objects dominating a given set of objects on class level. It is very useful to quickly find out who is responsible for a set of objects. Using the fact that every object has just one immediate dominator (unlike multiple incoming references) the tool offers possibility to filter "uninteresting" dominators (e.g. java.* classes) and directly see the responsible application classes.

For example, if your interested objects are char arrays. The immediate dominators of all char arrays are all objects responsible for keeping the char[] alive. The result will contain most likely java.lang.String objects. If you add the skip pattern java.* , and you will see the non-JDK classes responsible for the char arrays.

Sunday, January 12, 2014

For instance, we have estimated that its live data size is approximately 1437MB using genconpar strategy.[4] In this article, we will show how to estimate the size of live data set using another strategy genpar. As you can guess, the live data size of a benchmark could be different using different GC strategies. Basically, live data size depends on:

Frequency of Objects Promoted from Young Gen (or Nursery) to Old Gen

Frequency of Collections

which, in turn, depend on which GC strategy used.

Importance of Estimating Live Data Size

The mark-and-sweep algorithm is the basis of all commercial garbage collectors in JVMs (including JRockit) today.[2,3] Here is how it works:[2]

When the system starts running out of memory (or some other such trigger) the GC is fired. It first enumerates all the roots and then starts visiting the objects referenced by them recursively (essentially travelling the nodes in the memory graph). When it reaches an object it marks it with a special flag indicating that the object is reachable and hence not garbage. At the end of this mark phase it gets into the sweep phase. Any object in memory that is not marked by this time is garbage and the system disposes it.

As can be inferred from the above algorithm, the computational complexity of mark and sweep is both a function of the amount of live data on the heap (for mark) and the actual heap size (for sweep). If your application has a large live data set, it could be a garbage collection bottleneck. Any garbage collection algorithm could break down given too large an amount of live data. So, it's important to estimate the size of live data set in your Java applications for any performance evaluation.

For better estimation, you want to consider using statistics only from the steady state. For example, our benchmark was run with following phases:

Ramp-up: 7800 secs

Steady: 4200 secs

In the above sample output, only the first and the last OC event were displayed (see the timestamp in red). Finally, live data size is estimated to be the average memory size after OC (shown in blue).

Using Excel to Compute Average

You can use Java code to parse the GC log and compute average memory size after Old Collections. An alternative way is using Excel, which is demonstrated here.

Before we start, we need to clean up data by replacing the following tokens:

"KB"
"->"

with spaces.

Then you open OC.txt and specify space as the delimiter for field extraction.

Select the "memory size after collection" field as shown above and compute the average as shown below:

Finally, the estimated live data size is 1359 MB.

Conclusions

If you have found that your live data set is large, you can improve your application's performance by:

Reducing it by improving your codes

For example, you should avoid object pooling which can lead both to more live data and to longer object life spans.

Giving your application a larger heap

As the complexity of a well written GC is mostly a function of the size of the live data set, and not the heap size, it is not too costly to support larger heaps for the same amount of live data. This has also the added benefit of it being harder to run into fragmentation issues and of course, implicitly, the possibility to store more live data.[3]

Finally, what size of live data set is considered large. It actually depends on what GC collector you choose. For example, if you choose JRockit Real Time as your garbage collector, practically all standard application, with live data sets up to about 30 to 50 percent of the heap size, can be successfully handled by it with pause times shorter than, or equal to, the supported service level.[3] However, if the live data size is larger than 50 percent, it could be considered too large.

Saturday, January 11, 2014

In this article, we will examine their Out-of-the-box (OOTB)[7] behaviors, especially on adaptive (or automatic) memory management in JRockit.

Adaptive Memory Management

JRockit was the first JVM to recognize that adaptive optimizations based on feedback could be applied to all subsystems in the runtime,[1] which include:

Code Generation

Memory Management

Threads and Synchronization

In this article, we will focus mainly on the memory management of R28. In R28, JRockit adaptively modifies many aspects of the garbage collection, but to a lesser extent than R27.[1]

Adaptive optimizations based on runtime feedback work in this way:[1] In the beginning, these changes are fairly frequent, but after a warm-up period and maintained steady-state behavior, the idea is that the JVM should settle upon an optimal algorithm. If, after a while, the steady-state behavior changes from one kind to another, the JVM may once again change strategies to a more optimal one.

So, JRockit may heuristically change garbage collection behavior at runtime, based on feedback from the memory system by doing:

Changing GC strategies

Automatic heap resizing

Getting rid of memory fragmentation at the right intervals

Recognizing when it is appropriate to "stop the world"

Changing the number of garbage collecting threads

-Xverbose:gc flag

To investigate the OOTB behavior of four mentioned Generational GC's (see also [2]), we have used:

-Xverbose:gc flag

Typically, the log shows things such as garbage collection strategy changes and heap size adjustments, as well as when a garbage collection take place and for how long.

OOTB Behavior

The OOTB behavior of four Generational GC's was investigated using one of our benchmarks, which has the following characteristics (see also [3,4]):

High churning rate

Allocating large objects

Here are the Average Response Time (ART; on relative scale) of four different GC strategies:

-Xgc:genpar

Baseline

-Xgc:gencon

-3.21%

-Xgc:genconpar

-36.56%

-Xgc:genparcon

-17.60%

After tests, it turns out that the default throughput GC (i.e., genpar) performs the best while other low-pausetimes GC's lag behind. There are a couple of reasons:

Large live data set

Our benchmark has large live data size (i.e., 1,471,425 KB) and we have assigned it a relative tight heap space (i.e., 2GB).

Concurrent sweeping phase cannot keep up with the workload generated from marking phase

Sweeping and compaction (JRockit uses partial compaction to avoid fragmentation) tend to be more troublesome for parallelization. When you allow Java threads to be run concurrently in the sweep phase, it makes sweeping run longer and slower because more bookkeeping and/or synchronization needed. Also, using fewer GC threads introduces the issue that the garbage collector cannot keep up with the growing set of dead objects.

Conclusions

Ideally, an adaptive runtime would never need tuning at all, as the runtime feedback alone would determine how the application should behave for any given scenario at any given time. However, the computational complexity of mark-and-sweep algorithm is both a function of the amount of live data on the heap (for mark) and the actual heap size (for sweep). Depending on the amount of live data on the heap and system configuration, the OOTB behavior of chosen Generational GC's may or may not be able to keep up the garbage collections.

It is often argued that automatic memory management can slow down execution for certain applications to such an extent that it becomes impractical. This is because automatic memory management can introduce a high degree of non-determinism to a program that requires short response times. And, there are more bookkeeping or overhead. For example, it would need an Old GC to change garbage collection strategies. To avoid this, some manual tuning may be needed to get good application performance.

Before attempting to tune the performance of an application, it is important to know where the bottlenecks are. That way no unnecessary effort is spent on adding complex optimizations in places where it doesn't really matter.

Friday, January 10, 2014

The mark and sweep algorithm is the basis of all commercial garbage collectors in JVMs today.[1,5,12] There are various implementations of mark and sweep algorithm in JRockit, which use different garbage collection strategies.

Unless you really know what you are doing, the –XgcPrio flag is the preferred way to tell JRockit what garbage collection strategies to run.[1] However, if you want further control over GC behavior, a more fine grained garbage collection strategy can be set from the command line using the –Xgc flag.

In this article, we will examine four Generational Garbage Collectors (Generational GCs) in JRockit, which uses nursery. Note that JRockit refers to the young generations[2] as nurseries.

Generational Garbage Collection Strategies

The garbage collection strategy is defined by nursery, mark strategy and sweep strategy. The nursery can either be present or not present. The mark and sweep phases can either be concurrent or parallel.

Here we only cover Generational GCs that use the nursery. For example, we will ignore "–Xgc:singlecon"—or single generational concurrent—in this discussion. As shown below, JRockit supports four different garbage collection strategies. They differ only in the using either concurrent or parallel in its mark and sweep phases.

-Xgc: option

Mark

Sweep

genconcon or gencon

Concurrent

Concurrent

genconpar

Concurrent

Parallel

genparpar or genpar (default)

Parallel

Parallel

genparcon

Parallel

Concurrent

GC Mode

Running JRockit with –Xverbose:gc will output plenty of verbose information on what the JVM memory management system is doing. This information includes garbage collections, where they take place (nurseries or old space), changes of GC strategy, and the time a particular garbage collection takes. For example, we have specified the following options:

-Xverbose:gc -Xverbosedecorations=level,module,timestamp,millis,pid

to find the GC mode of each strategy uses. As you can see, different strategies are designed for different purposes:

Stopping the World (STW)

Stopping the world means that collectors are halting all executing Java threads to run a collection cycle, thus guaranteeing that new objects are not allocated and objects do not suddenly become unreachable while the collector is running. This has the obvious disadvantage that the application can perform no useful work while a collection cycle is running.

Even though an algorithm such as mark and sweep may run mostly in parallel, it is still a complicated problem that references may change during actual garbage collections. If the Java application is allowed to run, executing arbitrary field assignments and move instructions at the same time as the garbage collector tries to clean up the heap, synchronization between the application and the garbage collector is needed. Stopping the world for short periods of time is necessary for most garbage collectors and this is one of the main sources of latency and non-determinism in a runtime.

Parallel vs Concurrent Collectors

The mark-and-sweep algorithm consists of two phases:[5]

Mark phase

In which, it finds and marks all accessible objects (or live objects).

Marking is very parallelizable and large parts of a mark phase can also be run concurrently with executing Java code.

Sweep phase

In which, it scans through the heap and reclaims all the unmarked objects.

Sweeping and compaction (JRockit uses partial compaction to avoid fragmentation), however, tend to be more troublesome for parallelization, even though it is fairly simple to compact parts of the heap while others are swept, thus achieving better throughput.

Many stages of a mark and sweep garbage collection algorithm can be made to run concurrently with the executing Java application. Marking is the most critical of the stages, as it usually takes up around 90 percent of the total garbage collection time. The computational complexity of mark and sweep is both a function of the amount of live data on the heap (for mark) and the actual heap size (for sweep).

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[3] and G1[4] ).

Conclusions

In memory management, the time spent in GC is detrimental to an application's performance. So, minimizing the time spent in GC seems to be a good thing to achieve (or is it?). Collectors use simple stop-the-world strategy consumes less CPU time because it is simple and requires less bookkeeping. However, simple stop-the-world collectors halt all Java threads and they are not a good fit for pause critical applications. Note that lantency is caused by not spending CPU cycle executing Java code.

Optimizing for low lantencies is basically a matter of avoiding stopping the world and let the Java application run as much as possible. However, performing GC and executing Java code concurrently requires a lot more bookkeeping and thus, the total time spent in GC will be longer. Also, if the garbage collector gets too little total CPU time and it can't keep up with the allocation frequency, the heap will fill up and an OutOfMemoryError[6-8] will be thrown by the JVM. Therefore, another key to low latency is to keep heap usage and fragmentation at a proper level.

To conclude, the tradeoff in memory management is between maximizing throughput and maintaining low latencies. In the real world, we can't achieve both at the same time.

Wednesday, January 8, 2014

There are three main types of security providers in WebLogic Server that are involved in the authentication flow:

Authentication Providers

Identity Assertion Providers

A special type of Authentication provider that handles perimeter-based authentication

Principal Validation Providers

Primarily acts as a "helper" to an Authentication Provider to provide an additional protection of the Principal in a Subject

You can also configure a Realm Adapter Authentication provider that allows you to work with users and groups from previous releases of WebLogic Server. In this article, we group them as authentication security providers.

Authentication Security Providers

WebLogic Server includes numerous authentication security providers. Most of them work in similar fashion: given a username and password credential pair, the provider attempts to find a corresponding user in the provider's data store. These Authentication security providers differ primarily in:

In perimeter authentication, a system outside of WebLogic Server establishes trust through tokens (note that a token will be usually passed through the request headers).

If you are using perimeter-based authentication, you need to use an Identity Assertion provider.

Terminology

Before we start, let's cover some basic security concepts:

User

A user can be a person or a software entity, such as a Java client.

A user with a unique identity must be defined in a security realm[6] in order to access any WebLogic resources belonging to that realm.

When a user attempts to access a particular WebLogic resource, WebLogic Server tries to authenticate and authorize the user by checking the security role assigned to the user in the relevant security realm and the security policy of the particular WebLogic resource. Note that we only focus on the authentication process in this article.

Group

Groups are logically ordered sets of users. Usually, group members have something in common.

Managing groups is more efficient than managing large numbers of users individually.

An Authentication provider allows WebLogic Server to establish trust by validating a user.

You must have one Authentication provider in a security realm, and you can configure multiple Authentication providers in a security realm.

Authentication service in WebLogic Server is implemented using the JAAS standard.[3]

JAAS implements a Java version of the Pluggable Authentication Module (PAM) framework, which permits applications to remain independent from underlying authentication technologies.

Principal Validation Service/Provider

Primarily acts as a "helper" to an Authentication Provider to provide an additional protection of the Principal in a Subject by:

Signing the Principal populated by the LoginModule

Verifying the Principal retained in the client application code when making authorization decision.[10]

Identity Assertion Service/Provider

An Identity Assertion provider is a special type of Authentication provider that handles perimeter-based authentication and multiple security token types/protocols.

An Identity Assertion provider verifies the tokens and performs whatever actions are necessary to establish validity and trust in the token.

Identity Assertion providers support the mapping of a valid token to a user.

Each Identity Assertion provider is designed to support one or more token formats.

LoginModule

A LoginModule is a required component of an Authentication provider. It is the work-horses of authentication: all LoginModules are responsible for authenticating users within the security realm and for populating a subject with the necessary principals (users/groups).

Username/Password Authentication Process

Authentication is the process of verifying an identity claimed by or for a user or system process. An authentication process consists of two steps:

Identification—presenting an identifier to the security system.

Verification—presenting or generating authentication information that corroborates the binding between the entity and the identifier.

Authentication answers the question, Who are you? using credentials such as username and password combinations. An Authentication provider is used to prove the identity of users or system processes. The Authentication provider also stores, transports, and makes identity information available to various components of a system when needed. During the authentication process, a Principal Validation provider supports additional security protections for the principals (users and groups) contained within the subject, by first signing and later verifying the authenticity of those principals for each use.

In Figure 2, we show you the basic authentication flow of simple authentication. For the authentication flow of perimeter-based authentication, you can read [4] for details.

When a user attempts to log into a system using a username/password combination, WebLogic Server establishes trust by validating that user's username and password, and returns a subject that is populated with principals per JAAS requirements.[3] As Figure 2 also shows, this process requires the use of a LoginModule and a Principal Validation provider.

You can configure multiple authentication security providers in a security realm. You can also configure the JAAS Control Flag for each Authentication provider to control how it is used in a login sequence. Read [7] for more details.

Finally, Oracle recommends that you also configure the Password Validation provider,[8,9] which works with several out-of-the-box authentication providers to manage and enforce password composition rules. Whenever a password is created or updated in the security realm, the corresponding authentication provider automatically invokes the Password Validation provider to ensure that the password meets the composition requirements that are established.

Disclaimer

The statements and opinions expressed here are my own and do not necessarily represent those of Oracle.For your computer health, follow me @xmlandmore. To improve your personal health, follow me @travel2health.

About Me

Healthy pursuits are like traveling. We know there is a wonderland called wellness. But, there are no fixed routes to reach there. The pursuits need effort and determination. We cannot act like tourists who don't know where they've been. We must take notes of warning signs sent by our bodies.

On the journey to wellness, there are many dangers to be avoided; there are many footsteps to be taken; unfortunately, there are no short-cuts.

Travelers walking in the night follow North Star. Healthy pursuits work similarly. We know our goal; we know the signposts; we know the dangers on the road; we can adjust pace if we are tired; we can change travel plans due to the weather. But, We walk steadily and persistently. With my companionship, hopefully, your journey will be made easier.