有没有从Tomcat 采取线程转储.我想在特定时间监视Tomcat上正在运行的线程.
注意:我在Web逻辑上这样做,但我不知道如何在Tomcat上完成它.
我试图理解HotSpot JVM的内存结构,并与"方法区域"和"PermGen"空间这两个术语混淆.我提到的文档说,方法区包含类和方法的定义,包括字节代码.其他一些文档说它们存储在PermGen空间中.
那么我可以断定这两个内存区域是一样的吗?
我最近切换到Google App Engine Java SDK 1.7.3.从那时起,每次我将DeferredTasks提交到任务队列时,我的PermGen空间都用完了.
它发生在使用Java 6的MacOSX 10.7.5上
$ java -version
java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-11M3909)
Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01-434, mixed mode)
Run Code Online (Sandbox Code Playgroud)这是我发现问题时堆栈跟踪的一部分.
INFO: Successfully processed ../target/projectName/WEB-INF/queue.xml
Nov 1, 2012 3:04:00 PM com.google.appengine.api.taskqueue.dev.LocalTaskQueue init
INFO: LocalTaskQueue is initialized
Nov 1, 2012 3:04:01 PM org.quartz.simpl.SimpleThreadPool initialize
INFO: Job execution threads will use class loader of thread: 1255545583@qtp-1458850232-0
Nov 1, 2012 3:04:02 PM org.quartz.core.QuartzScheduler <init>
INFO: …Run Code Online (Sandbox Code Playgroud)限制Java JVM上Permgen空间大小的目的是什么?为什么不总是将它设置为最大堆大小?为什么Java默认这么少的64MB?他们是否试图强迫人们通过这样做来注意代码中的permgen问题?
如果我的应用程序使用85MB的permgen,那么将它设置为96MB可能是安全的,但是如果它只是主堆的主要部分,为什么设置它如此之小?允许JVM在堆允许的情况下使用尽可能多的PermGen会不会有效?
当我说-Xmx=1024m,这是否包括permgen即-XX:MaxPermSize=取自这1024米或它是分开的?
看着这个 我认为它需要1024米,但直到现在我还以为它们是分开的.
我在运行~300 JUnit测试并使用Spring上下文时看到'java.lang.OutOfMemoryError:PermGen space'.从那时起,我很难搞清楚PermGen吃了什么东西:
-XX:+TraceClassLoading和-XX:+TraceClassUnloading启用后,我会在执行最后20-30次测试之前看到没有其他"加载"事件OutOfMemoryError.后者似乎表明除了Class对象之外的东西正在填充PermGen,不是吗?如果是这样,它会是什么?例如,是否存在类实例存储在PermGen中的情况?
这是我的VM信息:
$ java -version
java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)
Run Code Online (Sandbox Code Playgroud)
有关
FWIW,我的问题的根源促成了这篇文章,结果有些微不足道:我假设Maven Surefire插件在MAfor_OPTS(或运行mvn的虚拟机实例)的情况下从虚拟机中继承VM设置 - 它没有(boo).必须在插件的配置中明确指定使用argLine的那些.HTH.
我正在尝试解决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空间被该类型的对象占用.
它是否正确?谢谢!
我在运行的jmap -heapJava应用程序上运行命令,这是我得到的:
C:\ Program Files\Java\jdk1.7.0_05\bin> jmap -heap 2384附加到进程ID 2384,请稍候...调试器已成功附加.服务器编译检测到 在新一代中使用并行线程的
JVM版本是23.1-b03
.
使用线程局部对象分配.
并发标记扫描GC
堆配置:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824(1024.0MB)
NewSize = 1310720(1.25MB)
MaxNewSize = 17592186044415 MB
OldSize = 5439488(5.1875MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 134217728(128.0 MB)
MaxPermSize = 201326592(192.0MB)
G1HeapRegionSize = 0(0.0MB)
堆用法:
新一代(Eden + 1 Survivor Space):
容量= 228261888(217.6875MB)
使用= 203794000(194.3531036376953MB)
free = 24467888(23.334396362304688MB)
89.28078260703775%使用
伊甸园空间:
容量= 202964992(193.5625MB)
使用= 198399360(189.2083740234375MB)
免费= 4565632(4.3541259765625MB)
97.75053226913141%使用
空间:
容量= 25296896(24.125MB)
使用= 5394640(5.1447296142578125MB)
free …
我知道,我有一个perm gen内存泄漏.使用jvisualvm进行性能分析表明,在进行热部署时(例如,在不杀死JVM的情况下停止和启动应用程序,在tomcat,WebSphere,WebLogic等中) - PermGen空间不断增加.
在阅读之后,使用jhat和其他高级工具,我意识到我可能WebAppClassLoader在其父类加载器中的某个类中引用了它.
即使我在jhat上做了一些基于JavaScript的大量查询,我也无法将其固定下来
是不是有一个简单的实用程序可以找出谁负责你的类加载器不被垃圾收集(从而允许垃圾收集由它加载的类)?
我试过JProfiler,jvisualvm,jhat和很多Google
所有LMGTFY的朋友 - 我花了大约一天半的阅读论坛一步一步的说明,没有运气.我正在寻找输出的实用程序或代码:
Y类的对象X是唯一的GC根,它可以防止您的类被删除.
假设我使用以下参数启动我的Java VM:
-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m
Run Code Online (Sandbox Code Playgroud)
512m PermGen空间是否会添加到1024m内存中,还是它们的一部分?或者换句话说,我的总内存消耗是1536米还是1024米?在后一种情况下,这是否意味着应用程序只有512m用于PermGen空间以外的目的?
如果这个问题显示对PermGen空间缺乏了解,请告诉我.;-)
permgen ×10
java ×9
jvm ×2
heap ×1
heap-memory ×1
jmap ×1
jvm-hotspot ×1
memory ×1
memory-leaks ×1
string ×1
task-queue ×1
thread-dump ×1
tomcat ×1