首页 > 编程知识 正文

虚拟机代理ip,JAVA 动态代理

时间:2023-05-06 20:40:52 阅读:141645 作者:3459

文章目录序言1、JHSDB介绍2、JHSDB实操结尾

前言JHSDB在JDK 9上正式提供,但以前是sa-jdi.jar包中的HSDB (可视化工)

具)和CLHSDB (命令行工具)的形式已经存在很久了。 它们都是JDK的正式成员,与JDK一起公开,因此不需要单独下载,使用也完全免费。

JDK提供了两个集成的多功能工具箱: JCMD和JHSDB。 这些工具箱往往比以前的旧工具更好、更强大,因为它们具有“后发优势”。 下表提供了JCMD、JHSDB和原始基础工具实现相同功能的简单比较。

由于本论文的主题是可视化的故障应对,所以不重点说明JCMD及JHSDB的命令行模式,通过实验说明JHSDB在图形模式下的功能。

另一方面,JHSDB介绍JHSDB是基于服务代理(Serviceability Agent,SA )实现的进程外调试工具。 服务代理是一组主要基于JNI代码较少的Java语言实现的API,用于映射HotSpot虚拟机中Java虚拟机的执行信息。 服务代理以HotSpot内部的数据结构为参照物进行设计,将这些c的数据抽象为Java模型对象。 这相当于HotSpot的c代码的镜像。 使用服务代理的API,独立的Java虚拟机进程可以分析其他HotSpot虚拟机的内部数据,并可以从HotSpot虚拟机进程内存中卸载的转储快照中恢复运行状态详细信息。 服务代理的工作方式与Linux上的GDB和Windows上的Windbg类似。 现在,让我们使用JHSDB分析代码列表中的代码,并通过实验回答静态obj、instanceObj和localObj这三个变量本身存储在哪里,而不是它们指向的对象。

/* * *静态obj、实例obj和本地obj存储在哪里? */publicclassjhsdb _ test case { staticclasstest } staticobjectholderstaticobj=new object holder (; objectholderinstanceobj=new object holder (; void foo () objectholderlocalobj=new object holder ); system.out.println(done ); ///在此处设置断点} } privatestaticclassobjectholder { } publicstaticvoidmain (string [ ] args (test test=newjhsdb _ tesse ) }当然,staticObj与Test的类型信息一起存储在方法区域中,instanceObj与Test的对象实例一起存储在Java堆中,localObject为foo )方法堆栈框架的本地需要在JHSDB中验证这一点。

二、JHSDB的实践操作首先要确保这三个变量已经分配到内存中,然后暂停程序,有间隙地执行

这只是在代码中的粗体打印语句中设置断点,然后在调试模式下运行程序。 由于支持JHSDB本身的压缩指针存在许多缺点,因此建议使用64位系统的读者在实验时禁用压缩指针。 此外,还建议您限制Java堆的大小,以便在后续操作期间可以加快在内存中查找对象的速度。 在本例中,笔者采用的运行参数如下。

- XM X10 m-xx : useserialgc-xx :-usecompressedoops 3358 www.Sina.com /

jps-l 8440 org.jetbrains.jps.cmdline.launcher 11180 jhsdb _ test case 15692 JDK.jcmd/sun.tools.jps.jps 3358 ww .

使用JHSDB hsdb --pid 11180命令打开的jhsdb接口如图所示。

阅读上面的JHSDB_TestCase类代码列表时,当您运行到断点位置时,将会创建三个ObjectHolder对象的实例。 只要是对象实例,它就一定会被分配给Java堆。 要了解引用这三个对象的指针存储在哪里,请从这三个对象开始,然后尝试从Java堆中查找。

首先,单击菜单中的Tools-Heap Parameters,结果如图所示。 由于笔者的运行参数指定使用串行收集器,因此在图中可以看到典型的串行分代内存布局。 Heap Parameters窗口包含正在努力的虎世代的jzdh、S1、S2和老世代的容量(

程序执行后通过jps查询到测试程序的进程ID,具体如下:

头参数: garbage-first头[

0x00007f32c7800000, 0x00007f32c8200000] region size 1024K

请读者注意一下图中各个区域的内存地址范围,后面还要用到它们。打开Windows->Console窗口,使用scanoops命令在Java堆的拼搏的老虎代(从jzdh起始地址到To Survivor结束地址)范围内查找ObjectHolder的实例,结果如下所示:

hsdb>scanoops 0x00007f32c7800000 0x00007f32c7b50000 JHSDB_TestCase$ObjectHolder0x00007f32c7a7c458 JHSDB_TestCase$ObjectHolder0x00007f32c7a7c480 JHSDB_TestCase$ObjectHolder0x00007f32c7a7c490 JHSDB_TestCase$ObjectHolder

果然找出了三个实例的地址,而且它们的地址都落到了jzdh的范围之内,算是顺带验证了一般情况下新对象在jzdh中创建的分配规则。再使用Tools->Inspector功能确认一下这三个地址中存放的对象,结果如图所示。


Inspector为我们展示了对象头和指向对象元数据的指针,里面包括了Java类型的名字、继承关
系、实现接口关系,字段信息、方法信息、运行时常量池的指针、内嵌的虚方法表(vtable)以及接口方法表(itable)等。由于我们的确没有在ObjectHolder上定义过任何字段,所以图中并没有看到任何实例字段数据,读者在做实验时不妨定义一些不同数据类型的字段,观察它们在HotSpot虚拟机里面是如何存储的。

接下来要根据堆中对象实例地址找出引用它们的指针,原本JHSDB的Tools菜单中有Compute
Reverse Ptrs来完成这个功能,但在笔者的运行环境中一点击它就出现Swing的界面异常,看后台日志是报了个空指针,这个问题只是界面层的异常,跟虚拟机关系不大,所以笔者没有继续去深究,改为使用命令来做也很简单,先拿第一个对象来试试看:

hsdb> revptrs 0x00007f32c7a7c458Computing reverse pointers...Done.Oop for java/lang/Class @ 0x00007f32c7a7b180

果然找到了一个引用该对象的地方,是在一个java.lang.Class的实例里,并且给出了这个实例的地址,通过Inspector查看该对象实例,可以清楚看到这确实是一个java.lang.Class类型的对象实例,里面有一个名为staticObj的实例字段,如图所示。


从《Java虚拟机规范》所定义的概念模型来看,所有Class相关的信息都应该存放在方法区之中,但方法区该如何实现,《Java虚拟机规范》并未做出规定,这就成了一件允许不同虚拟机自己灵活把握的事情。 JDK 7及其以后版本的HotSpot虚拟机选择把静态变量与类型在Java语言一端的映射Class对象存放在一起,存储于Java堆之中,从我们的实验中也明确验证了这一点。接下来继续查找第二个对象实例:

hsdb>revptrs 0x00007f32c7a7c480Computing reverse pointers...Done.Oop for JHSDB_TestCase$Test @ 0x00007f32c7a7c468

这次找到一个类型为JHSDB_TestCase$Test的对象实例,在Inspector中该对象实例显示如图所示。

这个结果完全符合我们的预期,第二个ObjectHolder的指针是在Java堆中JHSDB_TestCase$Test对象的instanceObj字段上。但是我们采用相同方法查找第三个ObjectHolder实例时, JHSDB返回了一个null,表示未查找到任何结果:

hsdb> revptrs 0x00007f32c7a7c490null

看来revptrs命令并不支持查找栈上的指针引用,不过没有关系,得益于我们测试代码足够简洁,人工也可以来完成这件事情。在Java Thread窗口选中main线程后点击Stack Memory按钮查看该线程的栈内存,如图所示。


这个线程只有两个方法栈帧,尽管没有查找功能,但通过肉眼观察在地址0x00007f32e771c998上的值正好就是0x00007f32c7a7c490,而且JHSDB在旁边已经自动生成注释,说明这里确实是引用了一个来自拼搏的老虎代的JHSDB_TestCase$ObjectHolder对象。至此,本次实验中三个对象均已找到,并成功追溯到引用它们的地方,也就实践验证了开篇中提出的这些对象的引用是存储在什么地方的问题。

JHSDB提供了非常强大且灵活的命令和功能,本篇的例子只是其中一个很小的应用,我们在实际开发、学习时,可以用它来调试虚拟机进程或者dump出来的内存转储快照,以积累更多的实际经验。


结尾 感谢大家的耐心阅读,如有建议请私信或评论留言。如有收获,劳烦支持,关注、点赞、评论、收藏均可,博主会经常更新,与大家共同进步

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。