Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我们可以查看JVM内存中的对象吗?_Java_Caching_Jvm_Production Environment - Fatal编程技术网

Java 我们可以查看JVM内存中的对象吗?

Java 我们可以查看JVM内存中的对象吗?,java,caching,jvm,production-environment,Java,Caching,Jvm,Production Environment,在工作中,我们发现在某些情况下(特别是速度较慢的情况下),我们会在重新启动时表现出不同的行为 我们猜测缓存没有正确初始化,或者可能是并发问题。。。 不管怎么说,除了生产,它不能在任何其他环境中复制 我们实际上没有要激活的记录器。。。这是一个旧组件 因此,我想知道是否有工具可以帮助我们查看JVM内存中存在的不同对象,以便检查缓存的内容… 谢谢大家! 编辑: 我没有直接访问生产服务器的权限,我们的应用服务器是weblogic 10,我没有指向该对象的指针,但我知道缓存对象类型 Edit2: 我们的服

在工作中,我们发现在某些情况下(特别是速度较慢的情况下),我们会在重新启动时表现出不同的行为

我们猜测缓存没有正确初始化,或者可能是并发问题。。。 不管怎么说,除了生产,它不能在任何其他环境中复制

我们实际上没有要激活的记录器。。。这是一个旧组件

因此,我想知道是否有工具可以帮助我们查看JVM内存中存在的不同对象,以便检查缓存的内容…

谢谢大家!

编辑:

我没有直接访问生产服务器的权限,我们的应用服务器是weblogic 10,我没有指向该对象的指针,但我知道缓存对象类型

Edit2:

我们的服务器运行在jre 1.5上,是否可以使用jmap?在jdk5中找不到它:( 此外,远程调试可能很好,但出于安全原因,我们不能

Edit3:

实际上,jhat+VisualVM对我来说还可以,我在dump中找到了我的对象,但是我无法正确地读取hashmap(包含大约60000项的对象)。。。 有没有一个工具可以以友好的方式读取concurrenthashmap?我需要在不手动浏览60k记录的情况下找到一个键的值(或它在映射中的存在)。 事实上,我在EclipseMat论坛上读到,使用它也是不可能的

Edit4: 经过一些经验之后,我真的很喜欢VisualVM之类的工具。也用过你的工具包。
有一些有用的功能,如OQL,可以找到您需要查看的正确实例…

您有权访问指向对象的句柄/指针吗?如果有,您可以在调试模式下启动它,并在Eclipse之类的调试器中查看它。这将允许您检查变量等

或者,您可以编写一个小型记录器,以反射方式遍历类并记录正在发生的事情。所有这些都假设您有一个位置,可以在该位置开始进入代码,或者可以获取对缓存值的引用



编辑:正如我在评论中指出的,我不知道如何在没有某种引用或引用链接的情况下访问对象。例如,该对象是否封装在另一个对象中?如果是,您可以执行以下操作:

Class<?> objectClass = myPointer.getClass();
Field[] objectFields = objectClass.getDeclaredFields();
for (Field field : objectFields) {
    field.setAccessible(true);
    //Or whatever you would need to do to get the information you need
    System.out.println(field.get(myPointer).toString());
}

请注意,所有反射方法都会抛出异常,因此您需要适当地处理这些异常意味着您可以访问对象上的私有字段和方法。这是极其危险的-只有在绝对必要的情况下才使用它。

运行jmap转储大量对象实例相当容易,但我不知道您是否真正感兴趣

您还可以使用jmap对整个堆进行堆转储,通过该转储(和jhat),您可以看到对象关系(即什么对象指向什么),但不一定是对象内容

当然,数据在堆转储中,它不可见

我认为一些专业的分析器可以让您在堆转储中内省对象


否则,您最好在应用程序中添加一些特定的工具,以提供您正在寻找的特定内省,由自定义代码、JMX或其他任何东西触发。

这基本上是对Will所说内容的扩展。
我已经取得了巨大的成功,让我们的管理员对我们的生产系统进行了大量的转储,不过需要注意的是,在转储完成之前,您正在转储的特定服务器将没有响应。然后获取该文件并使用Eclipse MAT插件查看它。如果您不喜欢Eclipse,可以使用Netbeans和普通的VisualVM插件同样,这可能会创建一些大文件,但您可能需要在64位系统上运行。

我不认为Eclipse中的调试器是一个选项,因为“它在生产环境以外的任何环境中都不可复制。”@Andrew Hubbs:我个人在生产环境中使用了Eclipse调试—您必须在调试模式下启动系统,并将其设置为远程连接。这里有一些选项—这不容易,但有可能。我们的服务器不在同一个城市,我不知道他们是否可以在调试模式下启动生产weblogic,也不知道eit塞巴斯蒂安·洛伯:我建议使用威尔·哈东的建议-你可以得到一个heapdump,然后用建议的各种工具解析它。仅供参考-我第一次看到远程调试会话时,它也会连接到另一个城市的服务器。这是可能的,但听起来很简单比如heapdump对你来说是一个更好的选择。是的,我确实每天都在远程服务器上调试,但他们永远不会给我访问生产实例的权限……我不知道没有某种指针/变量引用就可以访问对象的方法。+1-我不知道堆转储。那将是错误的一两个月前对我很有用:)我们使用Java1.5在1.5JRE上可以使用jmap吗?我只在jdk6上找到了jmap,它无法与我的本地jre 1.5…+1 for Eclipse MAT一起工作-imo是最强大(免费)的堆可视化工具。强烈推荐,并且有很棒的插件以有趣的方式查看堆(例如,集合填充%)。
Field targetField = objectClass.getDeclaredField("myFieldName");
targetField.setAccessible(true);
MyOldObjectType target = (MyOldObjectType)targetField.get(myPointer);
//do whatever you need to do here