关于内存使用的问题

dahlwuyn 2013-07-05 01:25:49
在方法中可能要大量生成对象或者申请大片的内存,这时候是要尽早将引用置null呢,还是申请一片内存,重复利用的好?如果是前者,垃圾收集器应该是方便回收,但是申请内存耗费资源应该不少吧,而且垃圾收集器回收也比较慢,如果是后者,重复利用,自然效率更高,但是垃圾收集器就无法回收了,不知道是不是会影响系统的效率。
...全文
167 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
北吹 2013-07-05
  • 打赏
  • 举报
回复
引用 10 楼 dahlwuyn 的回复:
如果每次调用都需要申请若干KB,甚至更大的内存的时候,而且是在密集的计算之中,会发现申请内存的方法明显速度更慢
你多虑了,基本类型最大的也就是long类型,一共才8个字节,不可能存在一次调用几KB的情况。 你说的用个基本类型数组缓存,跟直接赋值的区别只在赋值时的效率上,计算中是没区别的。 只要一个基本类型变量被赋值后,这个变量相关的计算操作中,所有的中间值存储都在栈上进行,所有的计算靠的是CPU,跟作为值来源的数组一点关系都没有了。
dahlwuyn 2013-07-05
  • 打赏
  • 举报
回复
如果每次调用都需要申请若干KB,甚至更大的内存的时候,而且是在密集的计算之中,会发现申请内存的方法明显速度更慢
北吹 2013-07-05
  • 打赏
  • 举报
回复
太虚了,举个例子吧。 代码

	public static void main(String[] args){
		int[] a = new int[1];
		a[0] = 0;
		
		//都是给局部基本类型变量赋值0,但是b的效率要远高过c
		int b = 0;
		int c = a[0];
	}
反解析下这段代码的编译文件:

  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=4, args_size=1
         0: iconst_1
         1: newarray       int
         3: astore_1
         4: aload_1
         5: iconst_0
         6: iconst_0
         7: iastore
         8: iconst_0 //0压栈
         9: istore_2 //0弹出给变量b
        10: aload_1  //数组a的引用入栈
        11: iconst_0 //下标0入栈
        12: iaload   //查找数组a的下标0对应数值,并把该数值压栈
        13: istore_3 //刚才压入的数值弹出给变量c
        14: return
      LineNumberTable:
        line 3: 0
        line 4: 4
        line 7: 8
        line 8: 10
        line 9: 14
很明显,原本直接赋值只需要压栈出栈2步就行了,而按照你的想法,弄个堆内存数组做缓存,反而需要4步,而且第三步需要根据引用去堆内存找,效率不是大幅提高了,而是大幅降低了。
北吹 2013-07-05
  • 打赏
  • 举报
回复
引用 7 楼 dahlwuyn 的回复:
……我用的是int这样的数组……引用和本身的内容的区别我当然知道了
引用 3 楼 dahlwuyn 的回复:
重复利用当然可以了,在调用方法最开始的时候就申请一片内存,之后的系列相关的方法里把这个内存当作参数引入,然后把中间量放在这内存里不就行了,这样一来就不用再申请内存创建实例了
没看明白你什么意思。 如果你所说的“申请一片内存”是指基本类型的数组,那就意味着你说的中间量也是基本类型,基本类型的局部变量根本不会创建实例啊。基本类型的局部变量本身是保存在方法栈帧的局部变量区里面的,远比去堆内存里面的数组访问效率要高,
dahlwuyn 2013-07-05
  • 打赏
  • 举报
回复
……我用的是int这样的数组……引用和本身的内容的区别我当然知道了
北吹 2013-07-05
  • 打赏
  • 举报
回复
你创建一个Object数组,把第一个位置指向了object1,再把第一个位置改为NULL,object1并不会在内存消失,你只是消除了数组对这个object1的引用,什么时候这个对象被回收,JVM才有决定权。 就算你再把第一个位置再指向另一个对象object2,这个object2占用的内存也是在它被new出来的时候决定的,无论是和数组,还是和object1都没有一点关系。
北吹 2013-07-05
  • 打赏
  • 举报
回复
引用 4 楼 dahlwuyn 的回复:
我说的是指一个巨大的对象,比如大块的数组之类的东西
...你把引用和对象本身的概念弄混了。 对象数组里面存的只是引用,不是对象本身。真正占内存的是对象本身,这个内存你是没办法控制重复利用的。
dahlwuyn 2013-07-05
  • 打赏
  • 举报
回复
我说的是指一个巨大的对象,比如大块的数组之类的东西
dahlwuyn 2013-07-05
  • 打赏
  • 举报
回复
重复利用当然可以了,在调用方法最开始的时候就申请一片内存,之后的系列相关的方法里把这个内存当作参数引入,然后把中间量放在这内存里不就行了,这样一来就不用再申请内存创建实例了
北吹 2013-07-05
  • 打赏
  • 举报
回复
你怎么做到“申请一片内存,重复利用”? JAVA里面你没办法控制内存,你只能用new 申请堆内存创建对象,不能控制这片内存的清理,更不能指定再次使用这片内存。 如果方法内创建大量对象,可以考虑将部分用完的对象提前用代码显式地指向NULL。但是一般的方法不需要这么做,方法结束局部变量的引用都会自动失效的。
  • 打赏
  • 举报
回复
不用的尽早引用置null,这样垃圾回收器会回收掉,可以尽量释放内存

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧