所以我在远程盒子上看着一个带有jmap的堆,我想强制垃圾收集.如果不突然进入jvisualvm或jconsole和朋友,你怎么做?
我知道你不应该在强制垃圾收集的实践中 - 你应该弄清楚为什么堆很大/正在增长.
我也意识到System.GC()实际上并没有强制进行垃圾收集 - 它只是告诉GC你希望它发生.
话虽如此,有办法轻松做到这一点吗?我失踪了一些命令行应用程序?
我正在使用以下命令创建堆转储:
jmap -dump:file=DumpFile.txt <process-id>
Run Code Online (Sandbox Code Playgroud)
我打开了生成的文件--DumpFile.txt,但它不是可读格式.所以,请让我知道如何分析生成的文件中的数据.
我已经从我的java应用程序生成了一个堆转储,它已经使用该jmap
工具运行了几天- >这导致了一个大的二进制堆转储文件.
如何在IntellIJ IDEA中对此堆转储执行内存分析?
我知道有Eclipse和Netbeans的工具,但如果可能的话我宁愿使用IDEA.
分析的基本结果将告诉我每个类在内存中每个对象的实例数,以便我能够开始调试内存泄漏.
我正在使用jmap来获取堆的直方图.我不确定对象是什么被称为"[C","[S","[I"和"[B".谁知道?
$ jmap -histo 3299
num #instances #bytes class name
----------------------------------------------
1: 9804 19070632 [Ljava.util.HashMap$Entry;
2: 38074 6216960 [Ljava.lang.Object;
3: 62256 4727832 [C
4: 19665 3124744 <constMethodKlass>
5: 19665 2365864 <methodKlass>
6: 57843 2313720 java.lang.String
7: 1662 2060528 <constantPoolKlass>
8: 21121 1842344 [S
9: 37772 1743888 <symbolKlass>
10: 2554 1655632 [I
11: 63710 1529040 java.lang.Integer
12: 1662 1264184 <instanceKlassKlass>
13: 1515 1196224 <constantPoolCacheKlass>
14: 24351 1168848 java.util.HashMap$Entry
15: 18706 1047536 java.net.SocketTimeoutException
16: 4301 784416 [B
...
23: 2588 242616 [[I
Run Code Online (Sandbox Code Playgroud) 我一直在尝试jmap -histo
和jmap -dump
今天
按此顺序运行时
jmap -dump:format=b,file=heap.1 [pid]
jmap -dump:live,format=b,file=heap.2 [pid]
jmap -dump:format=b,file=heap.3 [pid]
Run Code Online (Sandbox Code Playgroud)
heap.3
类似于heap.2
不止heap.1
.特别是,我感兴趣的"死"对象heap.1
不存在heap.3
.
看到这个,我开始寻找可以告诉我应该期待的文档.我最接近的是这次讨论,来自briand和alanb的评论意味着在实践中我可以预期当我使用live选项时会发生这个GC; 但答案是五年了,论坛上的帖子对于规范来说似乎有些不正式.
我在哪里可以找到记录的当前行为?
当我使用heapdump时,我得到以下异常
jmap -F -dump:format = b,file =/tmp/heapdump/before.hprof 10737
Attaching to process ID 10737, please wait...
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.tools.jmap.JMap.runTool(JMap.java:179)
at sun.tools.jmap.JMap.main(JMap.java:110)
Caused by: java.lang.RuntimeException: Type "nmethodBucket*", referenced in VMStructs::localHotSpotVMStructs in the remote VM, was not present in the remote VMStructs::localHotSpotVMTypes table (should have been caught in the debug build of that VM). Can not continue.
at sun.jvm.hotspot.HotSpotTypeDataBase.lookupOrFail(HotSpotTypeDataBase.java:361)
at sun.jvm.hotspot.HotSpotTypeDataBase.readVMStructs(HotSpotTypeDataBase.java:252)
at sun.jvm.hotspot.HotSpotTypeDataBase.<init>(HotSpotTypeDataBase.java:87)
at sun.jvm.hotspot.bugspot.BugSpotAgent.setupVM(BugSpotAgent.java:568)
at sun.jvm.hotspot.bugspot.BugSpotAgent.go(BugSpotAgent.java:494)
at sun.jvm.hotspot.bugspot.BugSpotAgent.attach(BugSpotAgent.java:332)
at …
Run Code Online (Sandbox Code Playgroud) 我正在尝试解决permgen泄漏问题,并想问你们大家如何解释jmap -permstat的输出.
假设我有一个jmap -permstat报告,如下所示:
class_loader classes bytes parent_loader alive? type
<bootstrap> 4791 25941568 null live <internal>
0x00000007203ed508 0 0 0x00000007203ed228 dead com/example/object/SomeObjectType$FirstClassLoader@0x0000000something1
0x000000071dc17620 1 3056 0x0000000705e692a8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
0x000000071f26a898 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x0000000721c6dba0 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x000000071e36df20 0 100 null dead com/example/object/SomeClassLoader@0x0000000something3
0x000000072157c1b8 339 2069112 0x000000072157b8d8 dead com/example/object/SomeObjectType$SecondClassLoader@0x0000000something2
0x00000007128b7830 1 1912 0x0000000700056db8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
0x0000000707634360 1 3088 0x0000000700056db8 dead sun/reflect/DelegatingClassLoader@0x0000000something4
Run Code Online (Sandbox Code Playgroud)
以下是我将如何解释上述输出 - 请更正我在此过程中所犯的任何错误.
"类型"列中的值不是唯一的.我们看到一些出现三次的物体.但是,class_loader值在所有三个中都是唯一的; 因此,它们中的每一个都是一个独特的对象,占据了permgen空间.在这个例子中,每个占用100个字节; 因此,SomeClassLoader类型的对象占用了300字节的permgen空间.
如果classes值为非零,则此对象必须是某种类加载器,并且这指的是它引用的类的数量.(注意:在实际文件中,这三个对象在bytes列中都有零;我为这个例子添加了值.在实际操作中,我猜测如果classes列中有0,那就没办法了bytes值可以是零.)
如果alive值为"dead",则表示该对象已准备好进行垃圾回收,但JVM没有这样做.对于可能出现这种情况的原因,需要单独讨论.
如果parent_loader列中有一个值,那么这是一个由另一个类加载器引用的对象,并且在该对象被垃圾回收之前不能进行垃圾回收.
最后:1)如果我在报告中看到所有列出相同类型的500行,2)但是它们列出了不同的class_loader值,3)然后我可以在字节列4)中添加值,这将准确地表示多少permgen空间被该类型的对象占用.
它是否正确?谢谢!
我们最近遇到了一个JVM崩溃,留下了gcore命令生成的核心转储文件.我们想看一下文件的内容,找出导致崩溃的确切原因.
使用该jmap
命令,您应该能够将核心转储文件转换为hprof文件格式的文件,然后可以使用VisualVM和许多其他工具进行分析.我试过这个并收到错误消息.这是我运行的命令(在发生崩溃的同一个框中,使用相同的JVM):
jmap -dump:format=b,file=dump.hprof /usr/java/jdk1.6.0_16/bin/java core.dump.2878
Run Code Online (Sandbox Code Playgroud)
整个回应是:
> Attaching to core core.dump.8483 from executable /usr/java/jdk1.6.0_16/bin/java, please wait...
> Error attaching to core file: Can't attach to the core file
Run Code Online (Sandbox Code Playgroud)
这不是一个非常有用的错误消息.我想知道它是否是一个权限问题,但是我得到了运行该命令的相同消息,就像运行导致核心转储的JVM一样.我也想知道核心文件是否已损坏,所以我决定用它gdb
来查看我是否可以打开核心文件并查看其中的内容.这就是我得到的:
> gdb GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-37.el5_7.1) License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for …
Java中的"共享对象内存"和"堆内存"有什么区别.它是否像'共享对象内存'是'堆内存'的超集?
这个问题的来源是jmap的文档.它为打印'共享对象内存'和'堆内存'提供了不同的选项.