java内存变大_javac用-g编译class在运行时是否因为多了LocalVariableTable内存占用变大?...

问这个问题也只是一个推测,希望有更准确的回答,目前看是没有了,自己解释下自己的理解。

应该会多占用内存,具体多大需要看项目的代码量了,我司开发了4年的game,编译出来的jar包有10M左右的大小区别,展开在内存中的话应该相近。

具体什么是LocalVariableTable呢?

贴一 @RednaxelaFX 的关于LocalVariableTable的回答java能否获取到引用的名称?​www.zhihu.comzhihu-card-default.svg

作者:RednaxelaFX

链接:https://www.zhihu.com/question/29643012/answer/45121995

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先,Java里的对象并没有“名字”的通用概念,

引用也没有“名字”的概念,

变量则可以有名字的概念。

以题主的例子:

Object abc = new Object();

这个变量声明,赋值符号右手边的表达式所创建出来的对象并没有名字(不是“abc”);

右手边这个表达式产生的引用也没有名字;

而这个引用通过赋值传给了左手边一个有名字“abc”的变量。

所以题主真正想问的问题就是:能否获取变量的名字。

如果变量是静态变量或者成员变量(字段),那么它们的名字作为符号信息是一直存在Class文件并带到运行时的。所以在运行时还可以把名字找出来。

但如果题主想做的事情是类似:

nameof(foo.bar); //=> "bar" nameof(this.baz); //=> "baz"

抱歉,Java没有这么方便的功能。

如果变量是参数或局部变量,则其符号信息在正常执行中是不需要的,因而也不会被保留到Class文件里。只有当从Java源码编译到Class文件时指定保留了局部变量的符号信息,才有可能在运行时知道参数或局部变量的名字。

Class文件里有一种属性表叫做LocalVariableTable,是用来记录参数与局部变量名字的符号信息表。javac编译Java源码时默认不生成这个属性表,只有指定了-g或-g:vars才会生成它。

这个属性表主要用于支持Java的调试器,以便调试器可以把某个slot里的局部变量映射到某个名字上。

一般来说,程序不应该猜测局部变量到底映射到了局部变量区的第几个slot上;但是因为局部变量区的头n个slot是用来存储方法的参数的,参数的位置与名字的映射关系倒是可以很方便的通过LocalVariableTable找出来。

因而这个表也有被调试器之外的程序“滥用”。一个经典的例子就是Spring的LocalVariableTableParameterNameDiscoverer,传给它一个java.lang.reflect.Method|Constructor,它可以返回一个数组的参数名回来。它就是通过人肉parse出Class文件里的LocalVariableTable来把信息找出来的。

顺带放个传送门:http://www.valleytalk.org/wp-content/uploads/2011/05/Java_Program_in_Action_20110727.pdf

这个场景对LocalVariableTable来说是种“滥用”,所以到Java 8的时候,Class文件格式新增了一个MethodParameters属性表专门用来存储参数名。这个属性表javac默认不生成,要指定-parameters参数来生成。Java的核心反射API添加了新的java.lang.reflect.Parameter来让代码访问这个属性表的信息。

请参考Obtaining Names of Method Parameters:https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html

和 JEP 118: Access to Parameter Names at Runtime

言归正传,如果有一个局部变量foo,Java里有没有简单的办法可以做到:

nameof(foo); //=> "foo"

呢?

答案是没有。

要nameof()运算符,请用C# 6:C# - The New and Improved C# 6.0

想在Java语言层面添加个nameof()运算符其实不困难,稍微鼓捣下javac就好了。

真有人有需求而且愿意用定制的javac的话我可以写个patch。

但是要说服社区把nameof()运算符加到Java语言规范里就没那么容易了…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值