java中什么是逃逸对象_Java对象逃逸分析(EscapeAnalysis)

对象逃逸

概念:

如果某一个方法内部声明了一个局部变量,该变量只在方法内部使用,没有被方法返回或者作为参数传到方法之外的地方,那么这个变量就只在方法背部使用,则该对象是没有发生对象逃逸。反之变量被作为参数传出去或者作为返回值使用,这个对象就称之为方法逃逸,或者赋值给类变量等能被其他线程访问到的变量,称之为线程逃逸。

会发生对象逃逸的代码示例:

下面的代码userInfo对象在保存之后会返回,外面调用的地方会用到这个返回值,那么这个对象就发生了逃逸

public UserInfo saveUserInfo(String userName){

UserInfo userInfo = new UserInfo();

userInfo.setUserCode(userName);

userInfo.setPassword(PasswordUtil.random(6))

//其他DB操作等...

return userInfo;

}

下面的代码也发生了对象逃逸,因为对象作为参数传到其他方法中,会被其他方法调用

public void saveUserInfo(String userName){

UserInfo userInfo = new UserInfo();

userInfo.setUserCode(userName);

userInfo.setPassword(PasswordUtil.random(6))

//其他DB操作等...

syncUserInfo(userInfo);

return userInfo;

}

private void syncUserInfo(UserInfo userInfo){

//同步逻辑...

}

逃逸分析

逃逸分析解释

如果能证明对象没有发生逃逸行为,那么Java虚拟机是可以对该对象内存分配进行优化。具体如何优化呢,我们都知道Java对象主要是存储在堆内存中,堆内存也是所有线程共享的变量池,堆内存的资源是很宝贵的;同时虚拟机进行垃圾回收(YoungGC和FullGC)都会先计算整理,找出哪些对象能被回收的,这是一个耗时耗服务器计算资源的过程,如果一个对象能确定不会发生逃逸行为,那么虚拟机就可以将该对象分配到方法栈内存上面,这个对象就会随着方法栈帧出栈的时候一起销毁,不需要垃圾回收器去计算和回收了。在很多方法里面,这类没有发生逃逸的对象还是有很多的,如果这些对象在栈内存分配能充分利用起来,将会大大缓解垃圾收集器的压力。虚拟机在将字节码转换成机器码的时候,会对这个对象是否发生逃逸进行分析的过程称之为逃逸分析。

开启对象逃逸分析

-XX:+DoEscapeAnalysis,使用这个启动参数就可以开启虚拟机逃逸分析

-XX:+PrintEscapeAnalysis, 使用这个启动参数可以查看逃逸分析的结果

其他注意事项

我们知道栈内存分配的空间通常是很小的,所以如果大量的没有逃逸的对象被分配到栈内存中,会不会发生栈内存溢出?

回答是不会的,首先虚拟机在逃逸分析的时候会判断栈内存是否够用,如果不够用,那没办法只能继续放堆内存里面了,我无能为力。

如果我希望能充分利用栈内存,那么这里就引出一个虚拟机参数 -Xss,我们需要将他调大,来保证有更多的空间来分配逃逸对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值