serkan-ozal / jillegal

Java Off Heap Object Pool and On the Fly Instrumentation Tool
http://serkan-ozal.github.com/jillegal/
111 stars 13 forks source link

offheap demo fail #2

Open fancyerii opened 10 years ago

fancyerii commented 10 years ago

in the comment of last issue, you said However there are some problems for offheap part of project due to compact phase of GC. These problems can be handled by VM arguments but i am working on a better solution.

I do have a problem when testing offheap demo. How to solve this problem?

Used memory on heap before On-Heap allocation: 1017992 bytes Array for class with size 10000000 for class test.OffHeapDemo$SampleClass has be en allocated ... 22 Array for class test.OffHeapDemo$SampleClass has been allocated, got and set for 10000000 elements in 1036 milliseconds ... Used memory on heap after On-Heap allocation: 281828624 bytes Memory used by On-Heap allocation: 280810632 bytes

Used memory on heap before Off-Heap allocation: 863648 bytes [INFO] Using attach provider: sun.tools.attach.WindowsAttachProvider@d320d6 Class Path: D:\ubuntu\projects\jillegal\target\test-classes;D:\ubuntu\projects\j illegal\target\classes;C:\Windows\System32\config\systemprofile.m2\repository\t r\com\serkanozal\jillegal-agent\1.0.4-RELEASE\jillegal-agent-1.0.4-RELEASE.jar;C :\Windows\System32\config\systemprofile.m2\repository\com\sun\tools\1.6.2\tools -1.6.2.jar;C:\Windows\System32\config\systemprofile.m2\repository\tr\com\serkan ozal\jcommon\1.0.1-RELEASE\jcommon-1.0.1-RELEASE.jar;C:\Windows\System32\config\ systemprofile.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Windows\Syst em32\config\systemprofile.m2\repository\com\google\guava\guava\13.0\guava-13.0. jar;C:\Windows\System32\config\systemprofile.m2\repository\commons-lang\commons -lang\2.6\commons-lang-2.6.jar;C:\Windows\System32\config\systemprofile.m2\repo sitory\cglib\cglib\2.2\cglib-2.2.jar;C:\Windows\System32\config\systemprofile.m 2\repository\asm\asm\3.1\asm-3.1.jar;C:\Windows\System32\config\systemprofile.m 2\repository\org\javassist\javassist\3.17.1-GA\javassist-3.17.1-GA.jar;C:\Window s\System32\config\systemprofile.m2\repository\junit\junit\4.11\junit-4.11.jar;C :\Windows\System32\config\systemprofile.m2\repository\org\hamcrest\hamcrest-cor e\1.3\hamcrest-core-1.3.jar OS Name: Windows 7 Using ClassPath: D:\ubuntu\projects\jillegal\target\test-classes;D:\ubuntu\proje cts\jillegal\target\classes;C:\Windows\System32\config\systemprofile.m2\reposit ory\tr\com\serkanozal\jillegal-agent\1.0.4-RELEASE\jillegal-agent-1.0.4-RELEASE. jar;C:\Windows\System32\config\systemprofile.m2\repository\com\sun\tools\1.6.2\ tools-1.6.2.jar;C:\Windows\System32\config\systemprofile.m2\repository\tr\com\s erkanozal\jcommon\1.0.1-RELEASE\jcommon-1.0.1-RELEASE.jar;C:\Windows\System32\co nfig\systemprofile.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Windows \System32\config\systemprofile.m2\repository\com\google\guava\guava\13.0\guava- 13.0.jar;C:\Windows\System32\config\systemprofile.m2\repository\commons-lang\co mmons-lang\2.6\commons-lang-2.6.jar;C:\Windows\System32\config\systemprofile.m2 \repository\cglib\cglib\2.2\cglib-2.2.jar;C:\Windows\System32\config\systemprofi le.m2\repository\asm\asm\3.1\asm-3.1.jar;C:\Windows\System32\config\systemprofi le.m2\repository\org\javassist\javassist\3.17.1-GA\javassist-3.17.1-GA.jar;C:\W indows\System32\config\systemprofile.m2\repository\junit\junit\4.11\junit-4.11. jar;C:\Windows\System32\config\systemprofile.m2\repository\org\hamcrest\hamcres t-core\1.3\hamcrest-core-1.3.jar Agent path: C:\Windows\System32\config\systemprofile.m2\repository\tr\com\serka nozal\jillegal-agent\1.0.4-RELEASE\jillegal-agent-1.0.4-RELEASE.jar Agentmain: sun.instrument.InstrumentationImpl@13f9276 - Arguments: null Exception in thread "main" java.lang.ClassCastException: /30165213 cannot be cas t to test.OffHeapDemo$SampleClass at test.OffHeapDemo.demoObjectOffHeapPool(OffHeapDemo.java:142) at test.OffHeapDemo.main(OffHeapDemo.java:32) Sequential Off Heap Object Pool with size 10000000 for class test.OffHeapDemo$Sa mpleClass has been allocated ...

serkan-ozal commented 10 years ago

There must not be class like "test.OffHeapDemo$SampleClass". All packages must be start with "tr.com.serkanozal.jillegaltest" prefix. Did you clone "jillegal-demo" project?

fancyerii commented 10 years ago

I copy the codes and paste to my test package. do I need keep the package structure? how to use it for my project's package structure?

serkan-ozal commented 10 years ago

As normal, keeping project structure is not necessary. Can you send your sample project to me for understanding reason of failure?

fancyerii commented 10 years ago

I build jillegal with maven and generate a project by mvn eclipse:eclipse and import it. then I create a test package and the OffHeapDemo class file the content of OffHeapDemo is copied from your demo:

OffHeapDemo.java

package test;

import java.util.ArrayList; import java.util.List;

import tr.com.serkanozal.jillegal.offheap.domain.builder.pool.ArrayOffHeapPoolCreateParameterBuilder; import tr.com.serkanozal.jillegal.offheap.domain.builder.pool.DefaultExtendableObjectOffHeapPoolCreateParameterBuilder; import tr.com.serkanozal.jillegal.offheap.domain.builder.pool.ExtendableObjectOffHeapPoolCreateParameterBuilder; import tr.com.serkanozal.jillegal.offheap.domain.builder.pool.ObjectOffHeapPoolCreateParameterBuilder; import tr.com.serkanozal.jillegal.offheap.domain.model.pool.ObjectPoolReferenceType; import tr.com.serkanozal.jillegal.offheap.memory.DirectMemoryService; import tr.com.serkanozal.jillegal.offheap.memory.DirectMemoryServiceFactory; import tr.com.serkanozal.jillegal.offheap.pool.impl.ComplexTypeArrayOffHeapPool; import tr.com.serkanozal.jillegal.offheap.pool.impl.EagerReferencedObjectOffHeapPool; import tr.com.serkanozal.jillegal.offheap.pool.impl.ExtendableObjectOffHeapPool; import tr.com.serkanozal.jillegal.offheap.pool.impl.LazyReferencedObjectOffHeapPool; import tr.com.serkanozal.jillegal.offheap.pool.impl.PrimitiveTypeArrayOffHeapPool; import tr.com.serkanozal.jillegal.offheap.service.OffHeapService; import tr.com.serkanozal.jillegal.offheap.service.OffHeapServiceFactory; import tr.com.serkanozal.jillegal.util.JvmUtil;

@SuppressWarnings("unused") public class OffHeapDemo {

private static final int ELEMENT_COUNT = 10000000;
private static final int TOTAL_ELEMENT_COUNT = 10000;

public static void main(String[] args) throws Exception {
    OffHeapService offHeapService = OffHeapServiceFactory
            .getOffHeapService();

    demoObjectOffHeapPool(offHeapService);

    // demoLazyReferencedObjectOffHeapPool(offHeapService);
    // demoEagerReferencedObjectOffHeapPool(offHeapService);
    // demoComplexTypeArrayOffHeapPool(offHeapService);
    // demoPrimitiveTypeArrayOffHeapPool(offHeapService);
    // demoExtendableObjectOffHeapPoolWithLazyReferenceObjectOffHeapPool(offHeapService);
    // demoExtendableObjectOffHeapPoolWithEagerReferenceObjectOffHeapPool(offHeapService);
    // demoExtendableObjectOffHeapPoolWithDefaultObjectOffHeapPool(offHeapService);
}

private static void demoObjectOffHeapPool(OffHeapService offHeapService)
        throws Exception {
    long start, finish;
    long usedMemory1, usedMemory2;

    // ////////////////////////////////////////////////////////////////////////////////////

    JvmUtil.runGC();

    Thread.sleep(2000);

    // ////////////////////////////////////////////////////////////////////////////////////

    usedMemory1 = Runtime.getRuntime().totalMemory()
            - Runtime.getRuntime().freeMemory();
    System.out.println("Used memory on heap before On-Heap allocation: "
            + usedMemory1 + " bytes");

    start = System.currentTimeMillis();

    SampleClass[] array = new SampleClass[ELEMENT_COUNT];

    System.out.println("Array for class with size " + ELEMENT_COUNT
            + " for class " + SampleClass.class.getName()
            + " has been allocated ...");

    SampleLinkClass link1 = new SampleLinkClass();

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = new SampleClass();
        obj.setOrder(i);
        obj.setLink(link1);
        array[i] = obj;
    }

    long start2 = System.currentTimeMillis();

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = array[i];
        SampleLinkClass link = obj.getLink();
    }

    System.out.println(System.currentTimeMillis() - start2);

    finish = System.currentTimeMillis();

    System.out.println("Array for class " + SampleClass.class.getName()
            + " has been allocated, got and set for " + ELEMENT_COUNT
            + " elements in " + (finish - start) + " milliseconds ...");

    usedMemory2 = Runtime.getRuntime().totalMemory()
            - Runtime.getRuntime().freeMemory();
    System.out.println("Used memory on heap after On-Heap allocation: "
            + usedMemory2 + " bytes");

    System.out.println("Memory used by On-Heap allocation: "
            + (usedMemory2 - usedMemory1) + " bytes");

    // ////////////////////////////////////////////////////////////////////////////////////

    System.out.println("\n");

    // ////////////////////////////////////////////////////////////////////////////////////

    JvmUtil.runGC();

    Thread.sleep(2000);

    // ////////////////////////////////////////////////////////////////////////////////////

    usedMemory1 = Runtime.getRuntime().totalMemory()
            - Runtime.getRuntime().freeMemory();
    System.out.println("Used memory on heap before Off-Heap allocation: "
            + usedMemory1 + " bytes");

    start = System.currentTimeMillis();

    EagerReferencedObjectOffHeapPool<SampleClass> eagerReferencedObjectPool = offHeapService
            .createOffHeapPool(new ObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .type(SampleClass.class)
                    .objectCount(ELEMENT_COUNT)
                    .autoImplementNonPrimitiveFieldSetters(true)
                    .referenceType(ObjectPoolReferenceType.EAGER_REFERENCED)
                    .build());

    JvmUtil.runGC();

    Thread.sleep(2000);

    System.out.println("Sequential Off Heap Object Pool with size "
            + ELEMENT_COUNT + " for class " + SampleClass.class.getName()
            + " has been allocated ...");

    DirectMemoryService directMemoryService = DirectMemoryServiceFactory
            .getDirectMemoryService();

    SampleLinkClass link2 = new SampleLinkClass();

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = eagerReferencedObjectPool.get();
        obj.setOrder(i);
        obj.setLink(link2);
    }

    long start1 = System.currentTimeMillis();

    SampleClass[] objArray = eagerReferencedObjectPool.getObjectArray();
    for (int i = 0; i < objArray.length; i++) {
        SampleClass obj = objArray[i];
        SampleLinkClass link = obj.getLink();
    }

    System.out.println(System.currentTimeMillis() - start1);

    finish = System.currentTimeMillis();

    System.out.println("Sequential Off Heap Object Pool for class "
            + SampleClass.class.getName()
            + " has been allocated, got and set for " + ELEMENT_COUNT
            + " elements in " + (finish - start) + " milliseconds ...");

    usedMemory2 = Runtime.getRuntime().totalMemory()
            - Runtime.getRuntime().freeMemory();
    System.out.println("Used memory on heap after Off-Heap allocation: "
            + usedMemory2 + " bytes");

    System.out.println("Memory used by Off-Heap allocation: "
            + (usedMemory2 - usedMemory1) + " bytes");
}

private static void demoLazyReferencedObjectOffHeapPool(
        OffHeapService offHeapService) {
    LazyReferencedObjectOffHeapPool<SampleClass> lazyReferencedSequentialObjectPool = offHeapService
            .createOffHeapPool(new ObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .type(SampleClass.class).objectCount(ELEMENT_COUNT)
                    .referenceType(ObjectPoolReferenceType.LAZY_REFERENCED)
                    .build());

    System.out
            .println("Lazy Referenced Sequential Off Heap Object Pool for class "
                    + SampleClass.class.getName()
                    + " has been allocated ...");

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = lazyReferencedSequentialObjectPool.get();
        obj.setOrder(i);
        System.out
                .println("New object has been retrieved from off heap pool and set order value to "
                        + i);
    }

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = lazyReferencedSequentialObjectPool.getAt(i);
        System.out.println("Order value of " + i
                + ". object at off heap pool: " + obj.getOrder());
    }

    System.out.println("\n\n");
}

private static void demoEagerReferencedObjectOffHeapPool(
        OffHeapService offHeapService) {
    EagerReferencedObjectOffHeapPool<SampleClass> eagerReferencedSequentialObjectPool = offHeapService
            .createOffHeapPool(new ObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .type(SampleClass.class)
                    .objectCount(ELEMENT_COUNT)
                    .referenceType(ObjectPoolReferenceType.EAGER_REFERENCED)
                    .build());

    System.out
            .println("Eager Referenced Sequential Off Heap Object Pool for class "
                    + SampleClass.class.getName()
                    + " has been allocated ...");

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = eagerReferencedSequentialObjectPool.get();
        obj.setOrder(i);
        System.out
                .println("New object has been retrieved from off heap pool and set order value to "
                        + i);
    }

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = eagerReferencedSequentialObjectPool.getAt(i);
        System.out.println("Order value of " + i
                + ". object at off heap pool: " + obj.getOrder());
    }

    System.out.println("\n\n");
}

private static void demoComplexTypeArrayOffHeapPool(
        OffHeapService offHeapService) {
    ComplexTypeArrayOffHeapPool<SampleClass> complexTypeArrayPoolWithNoInit = offHeapService
            .createOffHeapPool(new ArrayOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .type(SampleClass.class).length(ELEMENT_COUNT)
                    .initializeElements(false).build());

    System.out
            .println("Complex Type Off Heap Array Pool with no initialization for class "
                    + SampleClass.class.getName()
                    + " has been allocated ...");

    SampleClass[] complexArrayWithNoInit = complexTypeArrayPoolWithNoInit
            .getArray();

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = new SampleClass();
        obj.setOrder(i);
        complexTypeArrayPoolWithNoInit.setAt(obj, i); // Note that
                                                        // "array[i] = obj"
                                                        // is not valid,
                                                        // because JVM
                                                        // doesn't know
                                                        // array created at
                                                        // off-heap
        System.out
                .println("New complex typed element has been created on heap and "
                        + "assigned to off heap pool array " + i);
    }

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        SampleClass obj = complexArrayWithNoInit[i];
        System.out.println("Order value of " + i
                + ". element at off heap pool: " + obj.getOrder());
    }

    System.out.println("\n\n");
}

private static void demoPrimitiveTypeArrayOffHeapPool(
        OffHeapService offHeapService) {
    PrimitiveTypeArrayOffHeapPool<Integer, int[]> primitiveTypeArrayPool = offHeapService
            .createOffHeapPool(new ArrayOffHeapPoolCreateParameterBuilder<Integer>()
                    .type(Integer.class).length(ELEMENT_COUNT)
                    .usePrimitiveTypes(true).build());

    System.out.println("Primitive Type Off Heap Array Pool for class "
            + int.class.getName() + " has been allocated ...");

    int[] primitiveArray = primitiveTypeArrayPool.getArray();

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        primitiveArray[i] = i;
        System.out
                .println("New pritimive typed element has been assigned to off heap pool array "
                        + i);
    }

    for (int i = 0; i < ELEMENT_COUNT; i++) {
        int order = primitiveArray[i];
        System.out.println("Order value of " + i
                + ". element at off heap pool: " + order);
    }

    System.out.println("\n\n");
}

private static void demoExtendableObjectOffHeapPoolWithLazyReferenceObjectOffHeapPool(
        OffHeapService offHeapService) {
    LazyReferencedObjectOffHeapPool<SampleClass> sequentialObjectPool = offHeapService
            .createOffHeapPool(new ObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .type(SampleClass.class).objectCount(ELEMENT_COUNT)
                    .referenceType(ObjectPoolReferenceType.LAZY_REFERENCED)
                    .build());

    ExtendableObjectOffHeapPool<SampleClass> extendableObjectPool = offHeapService
            .createOffHeapPool(new ExtendableObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .forkableObjectOffHeapPool(sequentialObjectPool)
                    .build());

    System.out
            .println("Extendable Lazy Referenced Sequential Off Heap Object Pool for class "
                    + SampleClass.class.getName()
                    + " has been allocated ...");

    List<SampleClass> objList = new ArrayList<SampleClass>();

    for (int i = 0; i < TOTAL_ELEMENT_COUNT; i++) {
        SampleClass obj = extendableObjectPool.get();
        obj.setOrder(i);
        objList.add(obj);
        System.out
                .println("New object has been retrieved from off heap pool and set order value to "
                        + i);
    }

    for (int i = 0; i < TOTAL_ELEMENT_COUNT; i++) {
        SampleClass obj = objList.get(i);
        System.out.println("Order value of " + i
                + ". object at off heap pool: " + obj.getOrder());
    }

    System.out.println("\n\n");
}

private static void demoExtendableObjectOffHeapPoolWithEagerReferenceObjectOffHeapPool(
        OffHeapService offHeapService) {
    EagerReferencedObjectOffHeapPool<SampleClass> sequentialObjectPool = offHeapService
            .createOffHeapPool(new ObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .type(SampleClass.class)
                    .objectCount(ELEMENT_COUNT)
                    .referenceType(ObjectPoolReferenceType.EAGER_REFERENCED)
                    .build());

    ExtendableObjectOffHeapPool<SampleClass> extendableObjectPool = offHeapService
            .createOffHeapPool(new ExtendableObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .forkableObjectOffHeapPool(sequentialObjectPool)
                    .build());

    System.out
            .println("Extendable Eager Referenced Sequential Off Heap Object Pool for class "
                    + SampleClass.class.getName()
                    + " has been allocated ...");

    List<SampleClass> objList = new ArrayList<SampleClass>();

    for (int i = 0; i < TOTAL_ELEMENT_COUNT; i++) {
        SampleClass obj = extendableObjectPool.get();
        obj.setOrder(i);
        objList.add(obj);
        System.out
                .println("New object has been retrieved from off heap pool and set order value to "
                        + i);
    }

    for (int i = 0; i < TOTAL_ELEMENT_COUNT; i++) {
        SampleClass obj = objList.get(i);
        System.out.println("Order value of " + i
                + ". object at off heap pool: " + obj.getOrder());
    }

    System.out.println("\n\n");
}

private static void demoExtendableObjectOffHeapPoolWithDefaultObjectOffHeapPool(
        OffHeapService offHeapService) {
    ExtendableObjectOffHeapPool<SampleClass> extendableObjectPool = offHeapService
            .createOffHeapPool(new DefaultExtendableObjectOffHeapPoolCreateParameterBuilder<SampleClass>()
                    .elementType(SampleClass.class).build());

    System.out.println("Extendable Default Off Heap Object Pool for class "
            + SampleClass.class.getName() + " has been allocated ...");

    List<SampleClass> objList = new ArrayList<SampleClass>();

    for (int i = 0; i < TOTAL_ELEMENT_COUNT; i++) {
        SampleClass obj = extendableObjectPool.get();
        obj.setOrder(i);
        objList.add(obj);
        System.out
                .println("New object has been retrieved from off heap pool and set order value to "
                        + i);
    }

    for (int i = 0; i < TOTAL_ELEMENT_COUNT; i++) {
        SampleClass obj = objList.get(i);
        System.out.println("Order value of " + i
                + ". object at off heap pool: " + obj.getOrder());
    }

    System.out.println("\n\n");
}

// /////////////////////////////////////////////////////////////////////////////////////////

private static class SampleBaseClass {

}

private static class SampleClass {

    private int i1 = 5;
    private int i2 = 10;
    private int order;
    private SampleLinkClass link;

    public SampleClass() {

    }

    public int getI1() {
        return i1;
    }

    public int getI2() {
        return i2;
    }

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    public SampleLinkClass getLink() {
        return link;
    }

    public void setLink(SampleLinkClass link) {
        this.link = link;
    }

}

private static class SampleLinkClass {

    private long linkNo;

    public long getLinkNo() {
        return linkNo;
    }

    public void setLinkNo(long linkNo) {
        this.linkNo = linkNo;
    }

}

}

serkan-ozal commented 10 years ago

Thank you fancyerii, As soon as possible (possible this night), i will try your code.

serkan-ozal commented 10 years ago

Bug is about compaction of class definitions at GC cycle. I have not a good solution for this bug and I have already working on this bug. For a workaround you can add following parameters as VM argument.

For HotSpot JVM: "-XX:MarkSweepAlwaysCompactCount=999999999 -XX:HeapMaximumCompactionInterval=999999999 -XX:HeapFirstMaximumCompactionCount=999999999 -XX:-UseMaximumCompactionOnSystemGC -XX:-CMSCompactWhenClearAllSoftRefs -XX:-UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=999999999"

For JRockit: -XXnocompaction

For IBM JVM (WebSphere or J9): -Xnocompactgc -Xnoclassgc

These parameters must fix the bug and change you jillegal version to "1.0.6-RELEASE".

fancyerii commented 10 years ago

It works when I add -XX:MarkSweepAlwaysCompactCount=999999999 -XX:HeapMaximumCompactionInterval=999999999 -XX:HeapFirstMaximumCompactionCount=999999999 -XX:-UseMaximumCompactionOnSystemGC -XX:-CMSCompactWhenClearAllSoftRefs -XX:-UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=999999999

But I have a question, whether adding these VM arguments will make gc slower or affect the performance? Because the only reason we use offheap memory is performance.

noctarius commented 10 years ago

I think there is a discrepancy from what jillegal is at the current point in time and what you want to use it for. Serkan please correct me if I'm wrong but I think that it is not yet production ready (do to those kinds of problems) which means you shouldn't use it in production environments. With this in mind your question is irrelevant :-)

Don't take this in a mad way, but I think for production systems there are more proven solution - at least for now

serkan-ozal commented 10 years ago

Yes you are right Chris,

Jillegal is now far away from production usage especially offheap part. Now Jiilegal is at experimental state.

OffHeap part of Jillegal is different from other offheap solutions. In Jiilegal there is no extra serialization/deserialization for getting object from offheap or saving object to offheap. Because object itself lives on offheap and GC doesn't know these objects. But keeping objects on offheap can cause some problems. The most important problem is that class definitions may be moved on memory at compaction phase on GC cycle and then allocated objects on offheap points invalid class definition. To solve this problem, I am working on two solution.

  1. Pinnig class definitions on heap. So they won't be moved at compact phase.
  2. Hooking GC events with JVMTI (For Java 7 with MXBean) and update class pointers of all early allocated objects.

If I can solve this problem, I will publish it with new version, But nowadays, I am very busy and i have no time to working on this problem.

Cheers,

Serkan

fancyerii commented 10 years ago

hi serkan, thank your for your contribution of this tool. I am interested in offheap memory management because I have suffered from the uncertain gc stop the world pause. My application use large memory(greater than 20GB) and most of their lifetime is very long. where should I get started if I want to improve this myslef? My colleague suggest using c++ instead of java but I am used to java. c# has unmanaged objects as well as managed codes. why java don't have? I think many real time web application suffers from the gc pause problem

noctarius commented 10 years ago

As I said there are plenty of offheap solutions out there. Some can also do data distribution in a cluster, others just do offheap caching. A bit of googling will give you according projects. Most of them are hosted on github I think (beside fully commercial ones).

fancyerii commented 10 years ago

I keep a watchful eye on this field for a long time. raw byte array is hard to use. most of them are serialization/deserialization. I want a more better solution. that's why I am here I also tried zing jvm which is said to be better than hotspot but my experience tell me it's far from mature. and also it's not free.

fancyerii commented 10 years ago

Taobao(Biggest e-business company in China) has modified openjdk to extend java language to allow offheap objects(http://jvm.taobao.org/index.php/Jvm_gcih, written in Chinese). I do not think it's a good idea to modify java language. I think they don't want to give up their previous work on java and switching to other languages. But if they don't solve this problem, their boss may not be satisfied.

noctarius commented 10 years ago

As you see on this problems you know why mostly everybody uses serialization and while it has it's performance impacts it might be not as bad as you think (as long as you're not using java.io.Serializable itself). Zing isn't free that's true but it's a good product and every given dollar worth.

20GB of heap shouldn't be a problem at all. ParNew + CMS + good configuration of the spaces should work. Possibly you'll have to have a look at your object allocation rate. If really most objects are very long living (cache usecase) you're eden space seems to be to small so you have premature promotion which moved objects to tenured space to early and eventually trigger full gcs.

Maybe you should first have a look at things like this, jclarity has an awesome tool for analyzing your gc logs and giving good ideas of how to your gc configuration: http://www.jclarity.com/censum/

For more information about that you may even want to join the "Friends of jClarity" mailinglist where such topics are discussed in a deeper manner https://groups.google.com/a/jclarity.com/forum/#!forum/friends

Chris

fancyerii commented 10 years ago

thank you chris. I have heard so much suggestions like yours. But I still want to try off heap management if it's available

noctarius commented 10 years ago

If your problem is premature promotion offheap won't get you out of this.

I'm for myself working for a company that produces an off-heap solution (next to other things) and I'm implementing it. I say it maybe won't affect your problem.

If you just want to try the effect of offheap, just take a solution with serialization and see if it helps, if not you have to have a look inside your application and the gc.

For bigger systems the default gc config never works and even offheap will mostly no solution for it.

fancyerii commented 10 years ago

I mean I can control the life cycle of an object like in c++. The average performance is not so bad. But in some applaction, we can't bear the stop the world pause. yes, as you said, we can tackle this by adjust the vm args and using something like CMS or G1 collector. but we tried this and failed, that's why we turn to something like Zing jvm for help.

noctarius commented 10 years ago

Offheap is not for object allocation in a general sense. It might look like C++ malloc stuff but it is not. If you tried and failed with gc options you may want to look for a person to do that for you. I still think offheap is not an option for you to work around your problems.

serkan-ozal commented 10 years ago

Hi fancyerii,

I am thinking of another solution for compact problem of class definitions. All objects are refreshed with a call before they are used. This call is not expensive, it only updates class pointer atomically.

In addition, writing GC hook with JNI using JVMTI would be so useful for me if anyone can help me :)

fancyerii commented 10 years ago

hi serkan I am interested about it. where should I get started ?

serkan-ozal commented 10 years ago

Hi Lili,

If you are interested in this project, maybe you can implement a synchronous like in this reference:

http://stackoverflow.com/questions/2057792/garbage-collection-notification

If I can get all notifications of GC events, I check if class definition has moved on memory. If it has been moved, I will update class pointers of all objects of that pool.