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…
x
Reference in New Issue
Block a user