JAXBContext单例+工厂模式避免频繁GC

 生产系统运行一段时间CPU 飙高 占用89%以上。使用jstack 查看线程状态。

jstack pid > /opt/log.txt
pid 是进程ID

分析发现cpu 高的原因是有线程不停创建很多对象,导致频繁GC,最后CPU 飙高。


"http-nio-8101-exec-9" #30 daemon prio=5 os_prio=0 tid=0x00007f16d9d75000 nid=0x5b91 runnable [0x00007f16439f6000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.Throwable.fillInStackTrace(Native Method)
        at java.lang.Throwable.fillInStackTrace(Throwable.java:784)
        - locked <0x000000076adeb370> (a java.lang.reflect.InvocationTargetException)
        at java.lang.Throwable.<init>(Throwable.java:311)
        at java.lang.Exception.<init>(Exception.java:102)
        at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
        at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
        at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:125)
        - locked <0x00000006c0cab618> (a com.sun.xml.bind.v2.runtime.reflect.opt.Injector)
        at com.sun.xml.bind.v2.runtime.reflect.opt.Injector.inject(Injector.java:48)
        at com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector.prepare(AccessorInjector.java:51)
        at com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.get(OptimizedAccessorFactory.java:77)
        at com.sun.xml.bind.v2.runtime.reflect.Accessor$GetterSetterReflection.optimize(Accessor.java:326)
        at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.<init>(SingleElementLeafProperty.java:45)
        at sun.reflect.GeneratedConstructorAccessor46.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:88)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:135)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:465)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:484)
        at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.<init>(SingleElementNodeProperty.java:63)
        at sun.reflect.GeneratedConstructorAccessor61.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:88)
        at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:135)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:465)
        at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:299)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:103)
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:81)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:441)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
        at com.bsd.assets.util.lzyh.XmlUtils.convertToXml(XmlUtils.java:55)
        at com.bsd.assets.util.lzyh.XmlUtils.convertToXml(XmlUtils.java:39)
        at com.bsd.assets.channel.LzyhChannel.request(LzyhChannel.java:49)
        at com.bsd.assets.controller.LzyhController.pushUser(LzyhController.java:62)
        at sun.reflect.GeneratedMethodAccessor103.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:215)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        - locked <0x00000006cde392c0> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

解决方法使用JAXBContextFactory 工厂方法

package com.bsd.assets.util;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

public class JAXBContextFactory {
	private static JAXBContextFactory instance = new JAXBContextFactory();

	private static final Map<String, JAXBContext> INSTANCES = new ConcurrentHashMap<String, JAXBContext>();

	private JAXBContextFactory() {
	}

	/**
	 * Returns an existing JAXBContext if one for the particular namespace exists,
	 * else it creates an instance adds it to a internal map.
	 * 
	 * @param contextPath
	 *            the context path
	 * @throws JAXBException
	 *             exception in creating context
	 * @return a created JAXBContext
	 */
	public JAXBContext getJaxBContext(final String contextPath) throws JAXBException {

		JAXBContext context = INSTANCES.get(contextPath);
		if (context == null) {
			context = JAXBContext.newInstance(contextPath);
			INSTANCES.put(contextPath, context);
		}
		return context;
	}

	/*
	 * Returns an existing JAXBContext if one for the particular namespace exists,
	 * else it creates an instance adds it to a internal map. aram contextPath the
	 * context path
	 * @throws JAXBException exception in creating context
	 * @return a created JAXBContext
	 */
	public JAXBContext getJaxBContext(final Class<?> contextPath) throws JAXBException {
		JAXBContext context = INSTANCES.get(contextPath.getName());
		if (context == null) {
			context = JAXBContext.newInstance(contextPath);
			INSTANCES.put(contextPath.getName(), context);
		}
		return context;
	}

	/**
	 * Get instance.
	 * 
	 * @return Instance of this factory
	 */
	public static JAXBContextFactory getInstance() {
		return instance;
	}
}

JAXBContextFactory 使用

package com.bsd.assets.util.lzyh;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.slf4j.*;
import com.bsd.assets.util.JAXBContextFactory;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Date;

public class XmlUtils {
	
	private static final Logger log = LoggerFactory.getLogger(XmlUtils.class);

    /**
     * JavaBean转xml
     * 默认编码UTF-8
     */
    public static <T> String convertToXml(T obj) {
        return convertToXml(obj, "UTF-8");
    }

    /**
     * JavaBean转xml
     */
    public static <T> String convertToXml(T bean, String encoding) {
        String result = null;
        try {
        	JAXBContextFactory instance = JAXBContextFactory.getInstance();
        	JAXBContext context = instance.getJaxBContext(bean.getClass());
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//xml时同时进行格式化按标签自动换行
            marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);//是否省略xml头信息,默认不省略(false)
            StringWriter writer = new StringWriter();
            marshaller.marshal(bean, writer);
            result = writer.toString();
        } catch (Exception e) {
            log.error("JavaBean转xml异常", e);
        }
        return result;
    }


    /**
     * xml转成JavaBean
     * @param xml  xml
     * @param bean JavaBean
     * @return JavaBean
     */
    @SuppressWarnings("unchecked")
	public static <T> T convertToJavaBean(String xml, Class<T> bean) {
        T t = null;
        try {
        	JAXBContextFactory instance = JAXBContextFactory.getInstance();
        	JAXBContext context = instance.getJaxBContext(bean);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            t = (T) unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception e) {
            log.error("xml转成JavaBean异常", e);
        }
        return t;
    }

    /**date格式转换,这边格式是yyyy-MM-dd*/
    public static class JaxbDateAdapter extends XmlAdapter<String, Date> {

        @Override
        public Date unmarshal(String v) throws Exception {
            return DateUtil.parseDate(v, DateUtil.YMD, null);
        }

        @Override
        public String marshal(Date v) throws Exception {
            return DateUtil.format(v, DateUtil.YMD);
        }
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值