Zero-garbage large String deserialization in Java, Humongous object issue

前端 未结 3 1924
迷失自我
迷失自我 2020-12-15 00:36

I am looking for a way to deserialize a String from a byte[] in Java with as little garbage produced as possible. Because I am creating my own seri

相关标签:
3条回答
  • 2020-12-15 01:02

    Such objects are extremely hard to be efficiently garbage collected in G1.

    This may not be true any longer, but you will have to evaluate it for your own application. JDK Bugs 8027959 and 8048179 introduce new mechanisms for collecting humongous, short-lived objects. According to the bug flags you might have to run with jdk versions ≥8u40 and ≥8u60 to reap their respective benefits.

    Experimental option of interest:

    -XX:+G1ReclaimDeadHumongousObjectsAtYoungGC
    

    Tracing:

    -XX:+G1TraceReclaimDeadHumongousObjectsAtYoungGC
    

    For further advice and questions regarding those features I would recommend hitting the hotspot-gc-use mailing list.

    0 讨论(0)
  • 2020-12-15 01:06

    I have found a solution, which is useless, if you have an unmanaged environment.

    The java.lang.String class has a package-private constructor String(char[] value, boolean share).

    Source:

    /*
    * Package private constructor which shares value array for speed.
    * this constructor is always expected to be called with share==true.
    * a separate constructor is needed because we already have a public
    * String(char[]) constructor that makes a copy of the given char[].
    */
    String(char[] value, boolean share) {
        // assert share : "unshared not supported";
        this.value = value;
    }
    

    This is being used extensively within Java, e.g. in Integer.toString(), Long.toString(), String.concat(String), String.replace(char, char), String.valueOf(char).

    The solution (or hack, whatever you want to call it) is to move the class to java.lang package and to access the package-private constructor. This will not bode well with the security manager, but this can be circumvented.

    0 讨论(0)
  • 2020-12-15 01:09

    Found a working solution with simple "secret" native Java library:

    String longString = StringUtils.repeat("bla", 1000000);
    char[] longArray = longString.toCharArray();
    String fastCopiedString = SharedSecrets.getJavaLangAccess().newStringUnsafe(longArray);
    
    0 讨论(0)
提交回复
热议问题