BAEL-4795: Static garbage collected fields (#12693)
* BAEL-4795: Static garbage collected fields * BAEL-4795: Fix readAllBytes()
This commit is contained in:
parent
39acb99790
commit
06fc7ae257
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.staticgc;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
public class CustomClassloader extends ClassLoader {
|
||||
|
||||
public static final String PREFIX = "com.baeldung.classloader";
|
||||
|
||||
public CustomClassloader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
if (name.startsWith(PREFIX)) {
|
||||
return getClass(name);
|
||||
} else {
|
||||
return super.loadClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> getClass(String name) {
|
||||
String fileName = name.replace('.', File.separatorChar) + ".class";
|
||||
try {
|
||||
byte[] byteArr = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream(fileName));
|
||||
Class<?> c = defineClass(name, byteArr, 0, byteArr.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.staticgc;
|
||||
|
||||
public class GarbageCollectionExplicitExample {
|
||||
|
||||
public static final String METHOD_NAME = "printValue";
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
loadClass();
|
||||
System.gc();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The method loads a class and creates its instance. After the invocation of this method all the local variables go outside the scope.
|
||||
*/
|
||||
private static void loadClass() {
|
||||
try {
|
||||
final String className = "com.baeldung.classloader.GarbageCollectedStaticFieldHolder";
|
||||
CustomClassloader loader = new CustomClassloader(GarbageCollectionExplicitExample.class.getClassLoader());
|
||||
Class<?> clazz = loader.loadClass(className);
|
||||
Object instance = clazz.getConstructor().newInstance();
|
||||
clazz.getMethod(METHOD_NAME).invoke(instance);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.staticgc;
|
||||
|
||||
public class GarbageCollectionImplicitExample {
|
||||
|
||||
public static final String METHOD_NAME = "printValue";
|
||||
|
||||
public static void main(String[] args) {
|
||||
while (true) {
|
||||
loadClass();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The method loads a class and creates its instance. After the invocation of this method all the local variables go outside the scope.
|
||||
*/
|
||||
private static void loadClass() {
|
||||
try {
|
||||
final String className = "com.baeldung.classloader.GarbageCollectedStaticFieldHolder";
|
||||
CustomClassloader loader = new CustomClassloader(GarbageCollectionImplicitExample.class.getClassLoader());
|
||||
Class<?> clazz = loader.loadClass(className);
|
||||
Object instance = clazz.getConstructor().newInstance();
|
||||
clazz.getMethod(METHOD_NAME).invoke(instance);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.staticgc;
|
||||
|
||||
public class GarbageCollectionNullExample {
|
||||
|
||||
public static final String METHOD_NAME = "printValue";
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
CustomClassloader loader;
|
||||
Class<?> clazz;
|
||||
Object instance;
|
||||
try {
|
||||
final String className = "com.baeldung.classloader.GarbageCollectedStaticFieldHolder";
|
||||
loader = new CustomClassloader(GarbageCollectionNullExample.class.getClassLoader());
|
||||
clazz = loader.loadClass(className);
|
||||
instance = clazz.getConstructor().newInstance();
|
||||
clazz.getMethod(METHOD_NAME).invoke(instance);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
loader = null;
|
||||
clazz = null;
|
||||
instance = null;
|
||||
System.gc();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.staticgc;
|
||||
|
||||
public class StaticField {
|
||||
|
||||
private final String value;
|
||||
|
||||
public StaticField(final String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() {
|
||||
System.out.println("The object is garbage now");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.staticgc;
|
||||
|
||||
public class StaticFieldHolder {
|
||||
|
||||
private static StaticField staticField = new StaticField("Hello from static field");
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.classloader;
|
||||
|
||||
import java.util.Scanner;
|
||||
|
||||
public class GarbageCollectedStaticFieldHolder {
|
||||
|
||||
private static GarbageCollectedInnerObject garbageCollectedInnerObject =
|
||||
new GarbageCollectedInnerObject("Hello from a garbage collected static field");
|
||||
|
||||
public void printValue(){
|
||||
System.out.println(garbageCollectedInnerObject.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
class GarbageCollectedInnerObject {
|
||||
|
||||
private final String message;
|
||||
|
||||
public GarbageCollectedInnerObject(final String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() {
|
||||
System.out.println("The object is garbage now");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue