BAEL-4795: Static garbage collected fields (#12693)

* BAEL-4795: Static garbage collected fields

* BAEL-4795: Fix readAllBytes()
This commit is contained in:
Eugene Kovko 2022-09-05 17:45:31 +02:00 committed by GitHub
parent 39acb99790
commit 06fc7ae257
9 changed files with 177 additions and 0 deletions

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -0,0 +1,7 @@
package com.baeldung.staticgc;
public class StaticFieldHolder {
private static StaticField staticField = new StaticField("Hello from static field");
}

View File

@ -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");
}
}