JVM,常量池,堆和地址 [英] JVM, the constant pool, the heap and the addresses

查看:286
本文介绍了JVM,常量池,堆和地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我在Jasmin程序集中创建一个新项目然后存储它,我将使用指令aload进行操作,因为它是一个地址:

If I create a new item in Jasmin assembly and then store it, I do it with the instruction aload, since it's an address:

    new Object
    dup
    invokespecial.....
    astore_3 ; load the object reference into local variable 3

现在,如果我想从常量池中保存一个字符串...我将使用ldc创建它,然后也使用aload保存它:

Now, if I want to save a string from the constant pool... I would create it with ldc and then save it with aload as well:

    ldc "Great string"
    astore_3 ; save the reference to the actual string in the constant pool

现在...这些地址的格式和字节数相同吗?由于我使用相同的指令来加载和存储这些项,因此JVM必须能够区分属于常量池的地址和堆中的地址吗?

Now... are these addresses on the same form and the same number of bytes? Since I use the same instruction to load and to store these items, the JVM has to be able to make a distinction between addresses that belongs in the constant pool and addresses in the heap?

在检查字节码后,在我的情况下,常量池中的实际地址似乎只是一个1字节的索引(我想对常量池的主要引用也保存在某个地方)...现在我知道了那是对常量池中的som UTF8数据的引用,但是这是实际字符串所在的位置,还是仅仅是对字节数组的引用?基本上,我无法检查堆中新对象"的地址......,我需要弄清楚这两个内存区域如何使用相同形式的指令以及JVM如何管理确定地址是常量池中的偏移量还是堆中的对象?

Upon inspecting the bytecode, it seems that the actual address in the constant pool in my case is just a 1-byte index (I guess a main reference to the constant pool is kept somewhere as well)... now I know that that is a reference to som UTF8 data in the constant pool but is that where the actual string lies or is that just a reference to an array of bytes someplace else? Inspecting the address of the "new Object" in the heap I haven't been able to do..... basically, I need to work out how these two memory areas can use the same form of instructions and how the JVM manages to decide whether the address is an offset in the constant pool or an object in the heap?

推荐答案

JVM解释的字节码不一定与.class文件中写入的字节码相同.许多JVM在不同的执行阶段执行所谓的 bytecode重写.

The bytecode interpreted by JVM in not necessarily the same bytecode written in .class file. Many JVMs perform so-called bytecode rewriting on different stages of execution.

HotSpot JVM也是如此.初始化类后,HotSpot会使用JVM特定的fast_aldc字节码(引用CP缓存中的对象(即java.lang.String实例))重写引用常量池中的String条目的ldc字节码.第一次执行此类fast_aldc字节码时,JVM解析常量池条目,在Java Heap中创建一个String,并使用对该String的引用来填充CP缓存.在进一步执行相同的字节码后,JVM将立即从CP缓存中获取引用并将其推送到Java堆栈.

So does HotSpot JVM. When a class is initialized, HotSpot rewrites ldc bytecodes refering to String entries in the constant pool with JVM-specific fast_aldc bytecode which refers to objects (i.e. java.lang.String instances) in CP cache. When such fast_aldc bytecode is executed for the first time, JVM resolves the constant pool entry, creates a String in Java Heap and populates the CP cache with the reference to this String. Upon further executions of the same bytecode JVM will instantly get the reference from CP cache and push it to Java stack.

在解释了ldc字节码(或其重写形式)之后,栈顶将包含对Java Heap中的对象的有效引用. new字节码会产生相同类型的引用.因此,无需区分引用类型.

After the interpretation of ldc bytecode (or its rewritten form) the top-of-stack will contain a valid reference to an object in Java Heap. The same kind of reference is produced by new bytecode. So there is no need to distinguish reference types.

这就是口译员的工作方式.当然,在对方法进行JIT编译之后,就不再有字节码,常量池引用等了.所有这些都只是抽象.只是一个模型.

That's how interpreter works. Of course, after a method gets JIT-compiled, there is no more bytecodes, constant pool references etc. All of these are just abstractions. Just a model.

这篇关于JVM,常量池,堆和地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆