chuwe1
chuwe1
采纳率25%
2018-04-28 03:20

静态变量和静态代码块以及变量回收讨论!!!

5

public class NetWork {

    private static Retrofit retrofit;

    static {
        retrofit = new Retrofit.Builder()
                .client(builder.build())
                .baseUrl("...")
                .build();
    }

        private NetWork() {}

    private static HomeApi homeApi;

        public static HomeApi homeApi() {
        if (homeApi == null) {
            homeApi = retrofit.create(HomeApi.class);
        }
        return homeApi;
    }

}

这样写会出现因为内存不足导致retrofit和homeApi两个对象一起被回收。而在此调用NetWork.homeApi()和导致的空指针吗?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

5条回答

  • feelcycle_07 默默悟问 3年前

    不会被回收,如果内存不足会报OOM错误,应用基本就瘫了。if (homeApi == null) 线程不安全。

    点赞 评论 复制链接分享
  • weixin_42146825 the2thz 2年前

    不会的。
    首先,static变量在方法区,不在堆区,平时说的GC指的是堆区的GC。
    方法区GC和堆区GC不一样,方法区GC是卸载类,存在以下几个前提:
    1、该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例。
    2、加载该类的ClassLoader已经被回收。
    3、该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

    还未执行homeApi = retrofit.create(HomeApi.class);时,不满足卸载类的条件,所以不会收回空间。
    即使方法区没空间了,也不会回收将要被使用的空间,会报错Out of Memory,解决办法是调大永久代空间。
    不会随便回收空间的。

    另外,哪怕homeApi和retrofit在堆区,也不会回回收。
    如果没空间就回收这些还将要使用的变量,那所有的java程序都不要运行了。
    GC回收的是不会被使用的空间。堆区实在没空间了也不会回收,JVM会报错Out of Memory异常,让程序终止。
    此时只能加大堆区内存或者优化程序实现。

    点赞 评论 复制链接分享
  • qq_38455201 梦里梦不出梦里梦的梦 3年前

    类的静态变量和方法都保存在JVM的方法区,而方法区是没有GC的。这种情况下还是内存不足,说明整个程序已经崩溃了。

    点赞 评论 复制链接分享
  • m0_37742889 lickyson 3年前

    JVM运行时内存分配情况,在类加载阶段,静态成员被加载到方法区,也叫永久代。JVM类加载过程中有一个叫“类卸载”的过程,只要类没有别卸载,那么它就不会被回收,因为静态成员它是属于类的,不属于对象。
    从类加载角度来看,静态变量的初始化,要么定义时直接初始化,要么在静态代码块中初始化,要么在静态方法中初始化,但是不能在非静态方法中初始化。因为静态成员属于类。

    点赞 3 评论 复制链接分享
  • hu837389340 hu837389340 3年前

    静态变量不会被回收,类一开始加载的时候就加载到内存了,一直会存在于jvm的静态区,所以说static修饰的是很占内存的哦,如果不必要就别用静态修饰

    点赞 评论 复制链接分享

为你推荐