这个问题适用于曾经测试过Tomcat管理器中"查找泄漏"按钮的人,并获得了这样的结果:
以下Web应用程序已停止(重新加载,取消部署),但之前运行的类仍然在内存中加载,从而导致内存泄漏(使用分析器确认):
/leaky-app-name
我认为这与经常重新部署经常得到的"Perm Gen space"错误有关.
所以我在部署时在jconsole中看到的是我加载的类从大约2k到5k.然后你会认为取消部署应该将它们降回到2k,但它们保持在5k.
我也尝试使用以下JVM选项:
-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled
我确实看到Perm Gen空间的使用量非常小,但不是我预期的,并且加载的类计数没有下降.
那么有没有办法配置Tomcat或设计你的应用程序以便在取消部署时更好地卸载?或者我们是否在一些重要的调试会话后重新启动服务器?
Tomcat版本输出:
服务器版本:Apache Tomcat/6.0.29
服务器内置:2010年7月19日1458
服务器编号:6.0.0.29
操作系统名称:Windows 7
操作系统版本:6.1
体系结构:x86
JVM版本:1.6.0_18-b07
JVM供应商:Sun Microsystems Inc.
更新:
感谢celias的回答,我决定多做一些挖掘,我认为由于CXF,Spring和JAXB,我确定了应用程序的罪魁祸首.
在我学习了如何分析Java应用程序之后,我将分析器指向Tomcat并获取了一些堆转储和快照,以查看对象和类在内存中的外观.我发现在我的CXF/JAXB(wsdl2java)生成的类中使用的XML模式中的一些枚举在取消部署后仍然存在.根据我的堆转储,它看起来像是绑定到Map.免责声明:我承认我仍然有点绿色,分析和跟踪对象的调用树在Java中可能具有挑战性.
另外我应该提一下,我甚至没有调用该服务,只是部署然后取消部署它.对象本身似乎是通过部署时从Spring发起的反射加载的.我相信我遵循了在Spring中设置CXF服务的惯例.所以我不能100%确定这是Spring/CXF,JAXB还是反射的错误.
作为旁注:有问题的应用程序是使用Spring/CXF的Web服务,而XML恰好是一个相当复杂的模式(NIEM的扩展).
它就在那里,在它应该索引的包中.我还是打电话的时候
JAXBContext jc = JAXBContext.newInstance("my.package.name");
Run Code Online (Sandbox Code Playgroud)
我得到一个JAXBException说
"my.package.name"不包含ObjectFactory.class或jaxb.index
虽然它确实包含两者.
什么工作,但不是我想要的,是
JAXBContext jc = JAXBContext.newInstance(my.package.name.SomeClass.class);
Run Code Online (Sandbox Code Playgroud)
来自其他人的这个问题出现在一些邮件列表和论坛上,但似乎没有得到答案.
我在OpenJDK 6上运行它,所以我获得了源包并将调试器放入库中.它首先查找jaxb.properties,然后查找系统属性并且无法找到,它尝试使用com.sun.internal.xml.bind.v2.ContextFactory创建默认上下文.在那里,异常被抛出(内部ContextFactor.createContext(String ClassLoader, Map)),但我看不到发生了什么,因为源不在这里.
ETA:
从ContentFactory的源代码判断,我在这里发现,这可能是那些无法按预期工作的代码:
/**
* Look for jaxb.index file in the specified package and load it's contents
*
* @param pkg package name to search in
* @param classLoader ClassLoader to search in
* @return a List of Class objects to load, null if there weren't any
* @throws IOException if there is an error reading the index …Run Code Online (Sandbox Code Playgroud) 我想知道,JSON中的对象列表是什么的正确结构.
我们使用JAXB将POJO转换为JSON.
这是选择,请指导我什么是正确的.
foos: [
foo:{..},
foo:{..}
]
Run Code Online (Sandbox Code Playgroud)
要么
foos : [
{...},
{...}
]
Run Code Online (Sandbox Code Playgroud)
如果第一个结构是正确的,那么我应该使用什么JAXB注释来使结构正确.
试图通过这里的类投射异常:
FooClass fooClass = (FooClass ) unmarshaller.unmarshal(inputStream);
Run Code Online (Sandbox Code Playgroud)
抛出此异常:
java.lang.ClassCastException: javax.xml.bind.JAXBElement
Run Code Online (Sandbox Code Playgroud)
我不明白这个 - 因为这个类是由xjc.bat工具生成的 - 它生成的类我根本没有改变 - 所以这里应该没有转换问题 - unmarshaller应该真的给我一个类可以投射到FooClass.
关于我做错了什么的任何想法?
我目前正在使用JAXB生成java类以解组XML.现在我想创建一个与第一个非常类似的新模式,并使生成的类实现相同的接口.
比方说,我有两个模式文件,用于定义具有相似标签的XML:
adult.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Age" type="xs:integer" />
<xs:element name="Job" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
kid.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:element name="Person">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Age" type="xs:integer" />
<xs:element name="School" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
Run Code Online (Sandbox Code Playgroud)
使用JAXB和XJC我想生成两个类文件:
public class Adult implements Person {
...
public String getName() { ... }
public int getAge() { ... }
public String getJob { ... }
}
public class Kid implements Person …Run Code Online (Sandbox Code Playgroud) 这是一个非常简单的请求,但我没有找到办法.
我基本上试图在JAXB中设置一个角色,它表示只要遇到空字段,而不是在输出中忽略它,将其设置为空值.所以对于班级:
@XMLRootElement
Class Foo {
Integer num;
Date date;
….
}
Run Code Online (Sandbox Code Playgroud)
如果日期字段为空,则将其编组到XML文件中时,我的输出中没有该元素.我想要做的是包括输出中的所有字段; 如果它们为null,则将它们替换为 - 例如空白.所以输出应该是:
<foo>
<num>123</num>
<date></date>
</foo>
Run Code Online (Sandbox Code Playgroud)
谢谢,
Jalpesh.
我需要在编组到XML文件之前验证我的JAXB对象.在JAXB 2.0之前,可以使用javax.xml.bind.Validator.但是这已被弃用,所以我试图弄清楚这样做的正确方法.我熟悉马歇尔时间的验证,但就我而言,我只想知道它是否有效.我想我可以对一个临时文件或内存进行编组并抛弃它,但想知道是否有更优雅的解决方案.
我正在尝试使用CXF创建一个Web服务客户端来使用WCF Web服务.当我使用wsdl2java时,它使用JAXBElement类型而不是String生成对象.
我读到了使用jaxb bindings.xml文件设置generateElementProperty ="false"来尝试解决问题,但我正在使用的Web服务包含7个导入的模式.
如何指定generateElementProperty="false"所有七个模式,或者是否有办法将其应用于所有模式?
我想将一个转换OutputStream成一个String对象.我OutputStream在编组JAXB对象后返回了一个对象.
如果您尝试编组一个引用没有no-arg构造函数的复杂类型的类,例如:
import java.sql.Date;
@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
int i;
Date d; //java.sql.Date does not have a no-arg constructor
}
Run Code Online (Sandbox Code Playgroud)
使用JAXB实现作为Java的一部分,如下所示:
Foo foo = new Foo();
JAXBContext jc = JAXBContext.newInstance(Foo.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(foo, baos);
Run Code Online (Sandbox Code Playgroud)
JAXB将抛出一个
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions java.sql.Date does not have a no-arg default constructor
Run Code Online (Sandbox Code Playgroud)
现在,我理解为什么JAXB在解组时需要一个无参数的构造函数 - 因为它需要实例化对象.但是为什么JAXB在编组时需要一个无参数的构造函数?
另外,为什么Java的JAXB实现如果该字段为空则抛出异常,并且无论如何都不会被编组?
我在Java的JAXB实现中遗漏了一些东西,或者这些只是糟糕的实现选择?
java ×10
jaxb ×10
marshalling ×2
apache-felix ×1
cxf ×1
jaxb2 ×1
jaxb2-basics ×1
json ×1
memory-leaks ×1
osgi ×1
spring ×1
tomcat ×1
wcf ×1
web-services ×1
xjc ×1
xml ×1
xsd ×1