求教一下Java虚拟机问题

weixin_46004497 2019-12-11 10:56:26
敲代码的时候突然遇到这样的问题,假如现在我把虚拟机参数设置为-Xms2M -Xmx3M (设置虚拟机初始内存为2M,最大内存为3M)



各位请看,我在test1和test2方法中都循环创建10次,大小为1M的byte数组对吧。但是test1方法是写byte[] bb = null,test2是写byte[] bb = new byte[1024 * 1024 * 1]。这两种写法有什么实际区别?为什么运行test1就出现OutOfMemory异常,但是运行test2就没问题呢?

按照我自己的理解是,在test1方法中我声明了一个引用,byte[] bb,但是未指向任何有效内存。然后进入循环后,引用bb将会循环指向新分配的内存,但是上个循环分配的内存由于没有引用,不是会被GC清理掉嘛。test2里面声明的byte[] bb = new byte[1024 * 1024 * 1]不是属于一个强引用嘛,不会被GC回收,那为什么循环创建不会内存溢出?

...全文
77 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
我是你晶爷 2019-12-11
  • 打赏
  • 举报
回复
对象在内存里的状态分为三种,可达状态、可恢复状态、不可达状态,只有对象真正处于不可达状态时,系统才会真正回收对象所占用的资源。 test1方法,bb变量的作用范围是整个main方法,由于后续代码可以通过bb变量继续引用for循环中创建的对象,所以每次循环结束后对象处于可恢复状态,系统不会直接进行内存回收。 而test2方法中,bb变量的作用范围是循环体,在每次循环结束后,后续代码不可能通过bb变量引用创建的对象,对象的所有关联都被切断,处于不可达状态,所以内存被直接被回收。
weixin_46004497 2019-12-11
  • 打赏
  • 举报
回复
学习了,谢谢两位
qybao 2019-12-11
  • 打赏
  • 举报
回复
如LS所说
前者bb的作用域在方法内,离开了for,bb生命周期没有结束,new出来的对象没有释放(至少再下一次new之前没释放)。下一次new并完成bb=赋值后,上次new的对象才会被释放,才有可能被回收。
而后者bb的作用域在for,离开了for,bb生命周期结束,new出来的对象被释放回收

62,614

社区成员

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

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