Sunday, May 18, 2008

Object Queue/Pooling

Currently I am in design phase of a system which require high throughput and equally very high level for performance. In one of the design meeting, one of the very experienced member in the team make a very interesting remark, lets make object pool, this will increase the performance. Hmmm. That was really interesting for me and inspired me to write this blog on object pooling.

The myth about the object pooling goes like this “Object pooling works. The idea is that we can reuse objects by pooling them on and off free lists instead of using new and letting the garbage collector pick them up. Once you have more than one thread going off the pool, you need a synchronized free list, which has costs. If the list gets hot and contended, you can get scaling bugs. It gets complicated too fast and is not worth it for small to even moderate sized objects. Use it only for large objects.”

Object Pooling is about objects being pre-created and “pooled” for later use. The concept behind object pooling is that it is far cheaper to access an object from a pool of identical objects rather than create a new instance of the object. Creating a new instance involves the following steps:

  1. Loading the class if not already loaded.
  2. Obtaining the required memory from the heap.
  3. Creating an instance of the class within the obtained memory.

In the case of object pooling all these steps would have been performed for a pre-configured number of objects already. It was argued that one of these pre-configured objects could be utilized when a new instance is required. After use, this object would be returned to the pool. The problems with this paradigm are:

Pooling is not cheap. It requires the following steps as part of its execution:

  1. The pool should be locked when the object is being obtained.
  2. The pool needs to be potentially scanned for unused objects.
  3. The object needs to be marked as _used_.
  4. The pool can then be unlocked.

All these steps are not cheap since they involved synchronization locks across multiple threads.

  1. Pooling does not automatically support garbage collection. The object needs to be explicitly returned back to the pool to avoid memory leaks. Isn’t garbage collection one of the most compelling reasons to use Java or a similar language in the first place?
  2. Objects need to be coded to be “stateless”. Otherwise, the object may have to be re-initialized to ensure that it can be re-used back from the pool. This may be a feature of the pooling implementation but would add overhead during deallocation.

Hence it’s pretty conclusive that object pooling make no sense but resource pooling (like connection pool etc) make lots of sense.

Friday, May 9, 2008

OSGi

OSGi: - Open Services Gateway Initiative

Motivation

JEE world buzzwords have always been scalability, transaction management, security, high availability, manageability, monitoring etc. Trust me coming from my personal experience it is a stereotypical statement, but we do understand these problems and have successfully crafted solutions for each of them to an acceptable degree. But the major challenge lies in JEE based application deployment and things have basically remained unchanged since the very origin of JEE. No denying the implementation of modularization is implemented in code by dividing code base in modules, whether logical, physical or conceptual, at runtime they are seen as one monolithic application in which, making a change (be it large or small), requires a restart.

Modularity in java is achieved by using

· Java class files

· Java Archive (JAR) files

1.Provide form of physical modularity

2. May contain applications, extensions, or services

3. May declare dependencies

4. May contain package version and sealing information

Java provides the mechanisms to do these things, but they are

· Low level

· Error prone

· Ad hoc

Java's shortcoming are particular evident in its support for both modularity and dynamism

Java Modularity Limitations

· Limited scoping mechanisms

§ No module access modifier

· Simplistic version handling

1. Class path is first version found

2. JAR files assume backwards compatibility at best

· Implicit dependencies

1. Dependencies are implicit in class path ordering

2. JAR files add improvements for extensions, but cannot control visibility

· Split packages by default

1. Class path approach searches until it finds, which leads to shadowing or version mixing

2. JAR files can provide sealing

· Unsophisticated consistency model

1. Cuts across previous issues, it is difficult to ensure class space consistency

2. Missing module concept

3. Classes are too fine grained, packages are too simplistic, class loaders are too low level

· No deployment support

Java Dynamism Limitation

· Low-level support for dynamics

- Class loaders are complicated to use and error prone

· Support for dynamics is still purely manual

- Must be completely managed by the programmer

- Leads to many ad hoc, incompatible solutions

· Limited deployment support

- Unable to load modified classes at runtime

OSGi

OSGi framework provides

  • Simple component model
  • Component life cycle management
  • Service registry
  • Standard service definitions (separation of specification & implementation)

OSGi Resolves many deficiencies associated with standard Java support for modularity and dynamism

  • Defines a module concept

- Explicit sharing of code (i.e., importing and exporting)

  • Automatic management of code dependencies

- Enforces sophisticated consistency rules for class loading

  • Life-cycle management

- Manages dynamic deployment and configuration

OSGi framework is used as a modularity mechanism for Java and provides logical and physical system structuring. It has benefits for development and deployment. It provides sophisticated dynamic module life-cycle management. It simplifies creation of dynamically extensible systems, where system components can be added, removed, or rebound at run time while the system as a whole continues to function

OSGi framework promotes a service oriented interaction pattern as shown below: -

OSGi Features

  1. Simple component and packaging model

Bundles = JARs and contain java classes, resources and meta-data

That is, bundle represents a single component contained in a JAR file. A bundle defines a logical and physical modularity unit with

· Explicit boundaries

- External interface (i.e., exports)

- Internal class path

Java code, resources, and native libraries

· Explicit dependencies

- Package dependencies (i.e., imports)

· Explicit versioning

- Package version, bundle version

· Isolation via class loaders

· Packaging format (bundle JAR file)

    • Meta-data explicitly defines boundaries & dependencies as java package imports & exports.
    • Dependencies & associated consistency are automatically managed

The framework automatically resolves package dependencies when a bundle is activated

- Matches bundle’s imports to available exports

- Ensures package version consistency

· If a bundle cannot be successfully resolved, then it cannot be activated/used

Hence OSGi is a collection of bundles that interact via service interfaces and these bundles may be independently developed and deployed. Bundles and their associated services may appear or disappear at any time

  1. Defines a component life cycle

OSGi framework defines dynamic bundle life cycle

· Possible to install, update, and uninstall code at run time

· Automatic package dependency resolution

· Replaces low-level class loaders

  1. Explicitly considers dynamic scenarios
  2. Interaction through service interfaces
  3. Multi-version support

That is, it’s possible to have more than one version of a shared package in memory at the same time. As result for a given bundle, the service registry is implicitly partitioned according to the package versions visible to it

  1. Import version range

That is, exporters still export a precise version, but importers may specify an open or closed version range. It also eliminates existing backwards compatibility assumption.

Import-Package: ClaimService; version=“[1.0.0,1.5.0)”

Note: - Multi-version sharing and importing version ranges make implementation package sharing possible

  1. Arbitary export/import attributes

· Exporters may attach arbitrary attributes to their exports, importers can match against these arbitrary attributes

· Exporters may declare attributes as mandatory

· Mandatory attributes provide simple means to limit package visibility

· Importers influence package selection using arbitrary attribute matching

Import-Package: ServiceImpl;

version=“1.0.0”;

myattr=“myvalue”

  1. Package Consitency model

· Exporters may declare package “uses” dependencies

· Exported packages express dependencies on imported or other

exported packages, which constrain the resolve process

· The framework must ensure that importers do not violate constraints implied by “uses” dependencies.

Hence its pretty conclusive OSGi will provide in true sense modularization in java and much needed deployment ease