【问题标题】:What does the JVM do after it loads the library class..?JVM加载库类后会做什么......?
【发布时间】:2013-10-18 15:12:17
【问题描述】:

最近我在做一个关于JVM和字节码的实验。

我用这些代码sn-ps来测试。

import java.util.*;

public class Simple {

    private String a = "abcdefghijklmnopaqrstuvwaxyazaaabcdefghijklmnopaqrstuvwaxyazaabcdefghijklmnopaqrstuvwaxyazaabcdefghijklmnopaqrstuvwaxyaz";

    public int test()
    {
        String bb = "abcdefghijklmnopaqrstuvwaxyazaaabcdefghijklmnopaqrstuvwaxyazaabcdefghijklmnopaqrstuvwaxyazaabcdefghijklmnopaqrstuvwaxyaz";

        int a = 0;
        int b = a;
        int c = a + b;
        return c;
    }

    public static void main(String[] args) 
    {
        String cc = "abcdefghijklmnopaqrstuvwaxyazaaabcdefghijklmnopaqrstuvwaxyazaabcdefghijklmnopaqrstuvwaxyazaabcdefghijklmnopaqrstuvwaxyaz";

        Simple simple = new Simple();
        simple.test();

        Scanner input=new Scanner(System.in);
        System.out.println("how much money do you need?");
        double  number=input.nextDouble();
    }
} 

首先我使用 HotSpot 进行实验。在 Windows 上,我关闭了

-Djava.compiler=NONE

并使用 HeapMemView 查看 HotSpot 的堆内存。我可以找到“6162 6364..”的序列(与我的私有 String 变体匹配)并找到我的代码 sn-p 的字节码序列。

但是我找不到Java标准库的字节码序列..喜欢

Java.Lang.Obeject
Java.Lang.Math

怎么了..?以我的理解,我认为我应该在JVM的堆中找到它们的字节码序列..

然后我用 JRocket 再做一次.. 使用

   -Djava.compiler=NONE

打开编译器模式...但是这一次我什至无法在堆上找到我的字符串变体....

我被困在这里两天了.. 谁能帮帮我...?我真的很感激...

谢谢!

【问题讨论】:

  • “字节码序列”到底是什么意思?我不明白为什么当你运行一个不使用该类的程序时,你期望在堆中找到java.lang.Math。常量字符串的序列只是加载类时临时存在的临时工件。在创建 String 实例(使用不同的表示形式,通常是 UTF-16 字符数组)之后,内存可能会用于其他目的。
  • 您好 Holger,感谢您的回复,我想我可以通过找到加载的 Java 标准库的确切地址来对 ByteCode 进行 ROP...
  • 标准库通常没有固定的形式,也没有完全加载到JVM中。并且 JVM 运行时中的字节码序列与 jar 中的类文件中的字节码序列不同。 JVM 对字节码执行转换以减少内存消耗(例如通过共享常量)并提高性能(例如通过使用额外的非标准 JVM 特定操作码)。你不太可能找到你要找的东西。
  • @Holger 是的,它确实有很多复杂性......:(你能不能给我提供一些关于“额外的非标准 JVM 特定操作码”的文章......?我非常感谢您的帮助...

标签: java jvm bytecode jvm-hotspot jrockit


【解决方案1】:

我被困在这里两天了.. 谁能帮帮我...?我真的很感激...

我会首先关注您要解决的问题。也许您可以在问题中更清楚地说明您为什么要这样做。

在 Windows 上,我关闭了 -Djava.compiler=NONE

这只会改变代码编译为本机代码的方式。这不会以任何方式改变堆。

但是我找不到Java标准库的字节码序列..喜欢

字节码和类定义不在堆中,它们在 perm gen 中。

【讨论】:

  • 嗨,彼得,非常感谢!我知道它们在 JVM 的“perm gen”中,但是由于 Hotspot 和 JRockit 都是用 C++ 实现的,所以它们应该在 C++ 的堆中。而且我认为HeapMemView可以查看C++的堆..
  • @computereasy 在这种情况下,您应该寻找 UTF-16 编码的字符串。了解您为什么要这样做会很有帮助,因为这不太可能是做任何我能想到的事情的最简单方法。
  • 感谢您的回复。我在想是否可以在 Java ByteCode 上返回面向编程。(出于研究目的!!)我尝试找到某个 ByteCode 序列的内存地址。
  • 我只是尝试在JVM的堆上搜索某些字节码的相应二进制序列,这是我能想出的唯一可能的方法..你能告诉我“UTF-16”是什么意思吗,这与 ByteCode 的二进制表示有关系吗...?谢谢你
  • @computereasy 字节码通常以压缩格式存储在 JAR 文件中。这使得寻找它相当困难。但是 UTF-16 我的意思是en.wikipedia.org/wiki/UTF-16 这意味着如果没有正确的编码,您将无法搜索纯文本。如果您想深入了解 JVM 的内部结构,我建议您获取 OpenJDK 的源代码并对其进行修改以暴露您的兴趣。 IT 比原生堆更容易在代码中找到。
猜你喜欢
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
相关资源
最近更新 更多