JAVA程序员养成计划之JVM学习笔记(0)-一些注意事项

本文主要是针对JVM的一些小知识点进行梳理,如有什么地方有误或者不明白,欢迎指正讨论。
持续更新中… …

1. 内存回收

1.1. 线程栈帧中局部变量表的内存回收

  • 复用含义:线程的局部变量表是可以被JVM给复用的,首先要说的是变量槽,即slot,也就是局部变量表中的各个存放数据类型的位置。所谓复用,即局部变量表中的一个变量在确认不会被使用后,其他变量可以存放在这个位置上,以此来节省空间。
  • 内存泄露情况:当变量不再被任何方式引用的时候,如跳出该变量的作用域,与此同时,也没有新的变量对其复用,则局部变量表仍然保持着对它的引用,而局部变量表作为GC Roots的一部分,使得这一部分变量空间不能被JVM回收,如果后续要运行很长时间才会对这部分进行复用或者跳出线程,那么会使得这部分内存一直被占用着。
  • 避免方式:就如复用的含义一样,可以在变量不再使用后,对局部变量表进行一些操作,如例子中的willbegc1(),使得局部变量表更新,但是这样挺不科学的,因为看起来会和代码逻辑没啥关系。另一种方法就是在一个变量不再使用的时候给他赋值为null。
  • 例子
    public class jvmTestMain {
    public static void main(String []args){
        System.out.println("Start wontbegc():");
        wontbegc();
        System.out.println("Start willbegc1():");
        willbegc1();
        System.out.println("Start willbegc2():");
        willbegc2();
    }

    //不会被回收的placeholder
    public static void wontbegc(){
        {
            byte[] placeholder=new byte[64*1024*1024];
        }
        System.gc();
    }

    //会被回收的placeholder
    public static void willbegc1(){
        {
            byte[] placeholder=new byte[64*1024*1024];
        }
        int a=0;
        System.gc();

    }

    //会被回收的placeholder
    public static void willbegc2(){
        {
            byte[] placeholder=new byte[64*1024*1024];
            placeholder=null;
        }
        System.gc();
    }
}
  • 实验结果
    JAVA程序员养成计划之JVM学习笔记(0)-一些注意事项_第1张图片

你可能感兴趣的:(java,jvm,局部变量表)