diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/CustomClassloader.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/CustomClassloader.java new file mode 100644 index 0000000000..23f3e88393 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/CustomClassloader.java @@ -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); + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionExplicitExample.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionExplicitExample.java new file mode 100644 index 0000000000..db572469ea --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionExplicitExample.java @@ -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); + } + } +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionImplicitExample.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionImplicitExample.java new file mode 100644 index 0000000000..fc2b9879e2 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionImplicitExample.java @@ -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); + } + } +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionNullExample.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionNullExample.java new file mode 100644 index 0000000000..44bdca90ec --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/GarbageCollectionNullExample.java @@ -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); +} + + +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/StaticField.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/StaticField.java new file mode 100644 index 0000000000..3900950ff2 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/StaticField.java @@ -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"); + } +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/StaticFieldHolder.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/StaticFieldHolder.java new file mode 100644 index 0000000000..df7d794b3d --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/staticgc/StaticFieldHolder.java @@ -0,0 +1,7 @@ +package com.baeldung.staticgc; + +public class StaticFieldHolder { + + private static StaticField staticField = new StaticField("Hello from static field"); + +} diff --git a/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedInnerObject.class b/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedInnerObject.class new file mode 100644 index 0000000000..074d566d02 Binary files /dev/null and b/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedInnerObject.class differ diff --git a/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedStaticFieldHolder.class b/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedStaticFieldHolder.class new file mode 100644 index 0000000000..591ce17a32 Binary files /dev/null and b/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedStaticFieldHolder.class differ diff --git a/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedStaticFieldHolder.java b/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedStaticFieldHolder.java new file mode 100644 index 0000000000..304efadf59 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/resources/com/baeldung/classloader/GarbageCollectedStaticFieldHolder.java @@ -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"); + } +} \ No newline at end of file