05 关于局部变量名字的存储
Posted 蓝风9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了05 关于局部变量名字的存储相关的知识,希望对你有一定的参考价值。
@展开剩余8条评论↓ @mazai 验证了一下,变量名称存在局部变量表中了,和静态文件中的那样,不同的是运行时把符号引用Ljava/lang/String 换成了一个虚拟机中的内存地址 [图片]
mazai 21:47:11
符号引用转换成直接引用在解析阶段就会完成
花🌸 21:48:00
[图片]
花🌸 recalled a message
花🌸 21:49:26
所以:常量名称存在局部变量表中,根本不是在什么常量池里
花🌸 21:49:50
谢谢你的源码了
花🌸 21:49:55
@mazai
花🌸 21:50:02
[图片]
壹六得六 21:50:46
。。。你弄明白啥是常量池没有?
花🌸 21:50:49
@展开剩余8条评论↓ 收到自己看一把,目前我能得出的结果,也不知道对不对
mazai 21:51:04
不是啊。。运行时常量池也会有的
花🌸 21:52:35
运行时常量池,存的变量名称--->对应的地址吧
花🌸 21:53:17
针对的是我上面的那个程序哦,不是其它的
壹六得六 21:53:34
。。。随便那个程序都一样。。
mazai 21:53:41
你应该了解一下局部变量表的zuoyong
壹六得六 21:53:44
编译->装入->运行。。
壹六得六 21:53:50
都是这个流程。。
mazai 21:53:55
[图片]
花🌸 21:54:15
如果是自己定义的类:Person s1 = new Person() 那这个s1可以在运行时常量池中找到
花🌸 21:54:47
字段名称也可以在常量池找到
mazai 21:54:49
可以啊
mazai 21:55:06
[图片]
mazai 21:55:06
运行时常量池就是存储类信息的
壹六得六 21:55:57
...他把常量池搞的很混的。。
壹六得六 21:55:58
...
壹六得六 21:56:14
编译->装入->运行。。 想想是你,你会咋做
mazai 21:56:42
你实践之前这些概念要了解
mazai 21:56:59
不然你很容易方向走歪的
花🌸 21:57:40
[图片]
花🌸 21:58:10
[图片]这是验证的结果
成都-蓝风 21:59:08
这个应该输出的是 局部变量 的各个 slot 吧
壹六得六 22:00:20
标识符在编译期 肯定会写入到CLASS里面,作为符号表来管理,装入内存之后,这些标示符全部都要实例化起来
mazai 22:02:42
每个方法会有一个Code属性,Code里面会有一个LocalVaribleTable
mazai 22:03:13
LocalVaribelTable的信息就是从ConstantPool中引入的
花🌸 22:03:25
@成都-蓝风 TopicString对象运行时的数据,我没有看到变量名称,只找到名称对应的地址,然后地址里有值
成都-蓝风 22:04:01
嗯嗯, 你这应该是 使用的 jol 之类的吧
mazai 22:04:09
不可能没有吧,你是调试的吗
花🌸 22:04:12
@mazai 但是在运行时的常量池里,没有找到变量名称,怎么看你
壹六得六 22:05:07
多读书,自己去找。。
mazai 22:05:23
[图片]
花🌸 22:06:08
你这个是静态的文件呀
花🌸 22:06:10
[图片]
花🌸 22:06:30
[图片]这个是运行时的数据
成都-蓝风 22:07:56
constant pool
- holder: 0x00000007c008fc30
- cache: 0x00000001075abfb0
- resolved_references: 0x00000007bfb662f8
- reference_map: 0x00000001075ac000
- 1 : Method : klass_index=5 name_and_type_index=22
- 2 : String : 'value'
- 3 : Method : klass_index=4 name_and_type_index=24
- 4 : Class : 'com/hx/test05/Test18InvokeStatic' 0x00000007c008fc30
- 5 : Unresolved Class : 'java/lang/Object'
- 6 : Utf8 : '<init>'
- 7 : Utf8 : '()V'
- 8 : Utf8 : 'Code'
- 9 : Utf8 : 'LineNumberTable'
- 10 : Utf8 : 'LocalVariableTable'
- 11 : Utf8 : 'this'
- 12 : Utf8 : 'Lcom/hx/test05/Test18InvokeStatic;'
- 13 : Utf8 : 'main'
- 14 : Utf8 : '([Ljava/lang/String;)V'
- 15 : Utf8 : 'args'
- 16 : Utf8 : '[Ljava/lang/String;'
- 17 : Utf8 : 'name'
- 18 : Utf8 : 'Ljava/lang/String;'
- 19 : Utf8 : 'foo'
- 20 : Utf8 : 'SourceFile'
- 21 : Utf8 : 'Test18InvokeStatic.java'
- 22 : NameAndType : name_index=6 signature_index=7
- 23 : Utf8 : 'value'
- 24 : NameAndType : name_index=19 signature_index=7
- 25 : Utf8 : 'com/hx/test05/Test18InvokeStatic'
- 26 : Utf8 : 'java/lang/Object'
@花🌸 给你一个运行时的吧
成都-蓝风 22:07:56
[图片]
mazai 22:08:42
[图片]
mazai 22:08:50
这就是运行时数据区的内容啊,运行的时候有可能会添加,但是这些数据还是有的
mazai 22:09:11
我看不懂你的图
成都-蓝风 22:10:43
@mazai 你截图这个 是编译之后class文件里面的信息哦
mazai 22:11:05
是啊那你们怎么看
壹六得六 22:11:26
。。。肯定会有...
花🌸 22:11:58
我的那个图才是运行时的对象,对象常量池里我是真的没找到
成都-蓝风 22:12:14
上面 花 这个似乎是 HSDB 上面截得吧
花🌸 22:12:20
@成都-蓝风 你的怎么看的?大哥
花🌸 22:12:22
嗯
花🌸 22:13:56
如果是自己定义的类:Person s1 = new Person() 那这个s1可以在运行时常量池中找到
成都-蓝风 22:14:43
HSDB上面看不到 是因为常量池这部分数据运行时是放在 固定的存储的数据后面的, 这个就需要取了解 常量池的存储方式了
以及然后 配合 memory viewer 应该能看
花🌸 22:15:51
我试试
花🌸 22:16:36
那为啥[图片]
成都-蓝风 22:16:49
我觉得 可以暂时不用去关心这个, 其实就是 数据组织的方式而已
你理解成 常量池 里面有这些东西就行
花🌸 22:16:51
这个的话,他就能看到呢
成都-蓝风 22:17:02
啊 看啥
mazai 22:17:20
不用纠结了兄弟
mazai 22:17:22
肯定有的
花🌸 22:17:28
如果是自己定义的类:Person s1 = new Person() 那这个s1可以在运行时常量池中找到
mazai 22:17:40
没有jvm为啥要加载这些信息?
花🌸 22:18:07
不是纠结,单纯的想验证一下
花🌸 22:18:45
[图片]这个s1在,HSDB能看到
成都-蓝风 22:19:31
[图片]
花🌸 22:21:51
[图片]
成都-蓝风 22:22:41
[图片]
这几个 java.lang.String, 对应的是 局部变量
花🌸 22:22:45
我只找到变量名称对应的地址,他哥的,头大
花🌸 22:22:57
是的
花🌸 22:23:04
是局部变量
花🌸 22:24:02
类变量我能找得到,常量池里也有 就是[图片]这里面的,找不到
花🌸 22:24:39
哎
Me.S 22:25:27
完美。。。
成都-蓝风 22:25:47
vm 这一层 他不关心具体的变量名字是什么吧, 只是可能 他需要一些额外的支持, 所以 吧这些元数据存下来了
成都-蓝风 22:26:01
假设 compile 的时候 不生成调试的相关信息
成都-蓝风 22:26:02
master:test05 jerry$ javap -c -v Test18InvokeStatic.class
Classfile /Users/jerry/IdeaProjects/HelloWorld/src/main/java/com/hx/test05/Test18InvokeStatic.class
Last modified May 1, 2020; size 266 bytes
MD5 checksum aa5c9abbe4f3f629190e8eba1d16157a
public class com.hx.test05.Test18InvokeStatic
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#12 // java/lang/Object."<init>":()V
#2 = String #13 // value
#3 = Methodref #4.#14 // com/hx/test05/Test18InvokeStatic.foo:()V
#4 = Class #15 // com/hx/test05/Test18InvokeStatic
#5 = Class #16 // java/lang/Object
#6 = Utf8 <init>
#7 = Utf8 ()V
#8 = Utf8 Code
#9 = Utf8 main
#10 = Utf8 ([Ljava/lang/String;)V
#11 = Utf8 foo
#12 = NameAndType #6:#7 // "<init>":()V
#13 = Utf8 value
#14 = NameAndType #11:#7 // foo:()V
#15 = Utf8 com/hx/test05/Test18InvokeStatic
#16 = Utf8 java/lang/Object
public com.hx.test05.Test18InvokeStatic();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=2, args_size=1
0: ldc #2 // String value
2: astore_1
3: invokestatic #3 // Method foo:()V
6: return
public static void foo();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=0, locals=0, args_size=0
0: return
花🌸 22:26:21
不知道了,都不知道怎么验证了,单纯的想验证一下
成都-蓝风 22:26:30
[图片]
你会发现 对应这个例子, "name", 就没有生成了
敬清 22:27:45
" 花🌸 22:24:02
类变量我能找得到,常量池里也有
就是[图片] "
局部变量名称也没啥用吧,这名称应该只是在需要生成localVariableTable或者methodParameters才需要再class文件里被描述一下吧@花🌸
壹六得六 22:28:17
你把你的两个对象放在一起对比一下就知道了。。
敬清 22:28:17
如果不生成这俩个属性表,局部变量名 class文件里都不会被描述
敬清 22:28:30
毕竟虚拟机不关心局部变量名是啥
壹六得六 22:28:41
或者把你那个地址的值转成String出来看就知道了
壹六得六 22:28:59
" 敬清 22:28:30
毕竟虚拟机不关心局部变量名是啥 "
@敬清 [图片] 要关心
敬清 recalled a message
敬清 22:29:59
我感觉这个名称都不需要加载到虚拟机,只不过是在class文件里描述了一下,以便于反编译啥的
壹六得六 22:30:00
需要加载的
壹六得六 22:30:13
会保存为符号表
花🌸 22:30:48
谢谢蓝风@成都-蓝风
花🌸 22:31:15
[图片]
上面的这部分 我的这部分代码如下
package com.hx.test05;
/**
* InvokeStatic
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2020-05-01 15:03
*/
public class Test18InvokeStatic
// Test18InvokeStatic
public static void main(String[] args)
String name = "value";
foo();
// foo
public static void foo()
完
以上是关于05 关于局部变量名字的存储的主要内容,如果未能解决你的问题,请参考以下文章