首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Apache Tomcat7内存泄漏(怀疑单个对象)

Apache Tomcat7内存泄漏(怀疑单个对象)
EN

Stack Overflow用户
提问于 2012-10-04 08:10:19
回答 1查看 2.1K关注 0票数 2

我目前正在一台具有以下属性的机器上开发一个Java应用程序:

  • 12.04 64位
  • Sun java JDK版本7
  • Apache Tomcat 7.0.30
  • Netbeans IDE,版本7.1.2

我的项目包括一个SOAP服务接口,它维护内存中的共享对象.为了使对象对所有线程可见,我开发了一个Singleton。我在下面发布我的应用程序代码:

代码语言:javascript
复制
@WebService()
public class ETL_WS {

    private Singleton CAP_offer_coupon_map;

    public ETL_WS() { }

    /**
     * This method adds a single coupon record to the memory map.
     */
    @WebMethod
    synchronized public int singleCouponLoad(@WebParam(name =
            "CouponID") long coupon_id,
            @WebParam(name = "ProductCategoryID") long product_category_id,
            @WebParam(name = "DateTo") Date dateTo,
            @WebParam(name = "LocationID") Location location_id) {
        Coupon _c = new Coupon(coupon_id, product_category_id, dateTo);
        if(location_id != null)
            _c.setLocation(location_id);
        CAP_CouponOfferCollection _data = CAP_offer_coupon_map.getModel();
        Coupon _tmp = _data.getCoupon(coupon_id);
        if(_tmp == null)
            return -1;
        _data.insertCoupon(_c);
        return 0;
    }

    /**
     * This method adds a single offer record to the memory map.
     */
    @WebMethod
    synchronized public int singleOfferLoad(@WebParam(name =
            "OfferID") long offer_id,
            @WebParam(name = "ProductCategoryID") long product_category_id,
            @WebParam(name = "DateTo") Date dateTo,
            @WebParam(name = "LocationID") Location location_id) {
        Offer _o = new Offer(offer_id, product_category_id, dateTo);
        if(location_id != null)
            _o.setLocation(location_id);
        CAP_CouponOfferCollection _data = CAP_offer_coupon_map.getModel();
        Offer _tmp = _data.getOffer(offer_id);
        if(_tmp == null)
            return -1;
        _data.insertOffer(_o);
        return 0;
    }

    @WebMethod
    synchronized public String getAllCoupons() {
        CAP_CouponOfferCollection _data = CAP_offer_coupon_map.getModel();
        HashMap<Long, Coupon> _c = _data.getCoupons_map();
        return _c.toString();
    }

    @WebMethod
    synchronized public String getAllOffers() {
        CAP_CouponOfferCollection _data = CAP_offer_coupon_map.getModel();
        HashMap<Long, Offer> _o = _data.getOffers_map();
        return _o.toString();
    }

    @WebMethod
    synchronized public long getProductIdFromCouponId(@**WebParam(name
            = "CouponID") long coupon_id) {
        long _product_id = -1;
        CAP_CouponOfferCollection _data = CAP_offer_coupon_map.getModel();
        Coupon _c = _data.getCoupon(coupon_id);
        if(_c != null)
            _product_id = _c.getCoupon_id();
        return _product_id;
    }

    @WebMethod
    synchronized public long getProductIdFromOfferId(@WebParam(name = "OfferID") long 
            offer_id) {
        long _product_id = -1;
        CAP_CouponOfferCollection _data = CAP_offer_coupon_map.getModel();
        Offer _o = _data.getOffer(offer_id);
        if(_o != null)
            _product_id = _o.getOffer_id();
        return _product_id;
    }

}

Singleton包装器类如下所示:

代码语言:javascript
复制
public class Singleton {

    private static boolean _instanceFlag = false;

    private static final Singleton _instance = new Singleton();

    private static CAP_CouponOfferCollection _data;

    private Singleton() {
    _data = new CAP_CouponOfferCollection();
    _instanceFlag = true;
    }

    public static synchronized CAP_CouponOfferCollection getModel() {
    if(_instanceFlag == false) {
        _data = new CAP_CouponOfferCollection();
        _instanceFlag = true;
    }
    return _data;
    }
}

CAP_CouponOfferCollection类如下所示:

代码语言:javascript
复制
public class CAP_CouponOfferCollection {

    private HashMap<Long, Coupon> _coupons_map;

    private HashMap<Long, ArrayList<Long>> _product_to_coupons_map;

    private HashMap<Long, Offer> _offers_map;

    private HashMap<Long, ArrayList<Long>> _product_cat_to_offers_map;

    private static long _creation_time;

    public CAP_CouponOfferCollection() {
        _creation_time = System.currentTimeMillis();
        System.out.println("Creation of CAP_CouponOffer object: " +
            _creation_time);
    }

    synchronized public void insertCoupon(Coupon newCoupon) {
        if(_coupons_map == null) {
            _coupons_map = new HashMap<Long, Coupon>();
            _product_to_coupons_map =
                    new HashMap<Long, ArrayList<Long>>();
        }
        Long key = newCoupon.getCoupon_id();
        if(!_coupons_map.containsKey(key)) {
            _coupons_map.put(key, newCoupon);
            key = newCoupon.getProductCategory_id();
            if(_product_to_coupons_map.containsKey(key)) {
                ArrayList<Long> _c_list = _product_to_coupons_map.get(key);
                _c_list.add(newCoupon.getCoupon_id());
                _product_to_coupons_map.remove(key);
                _product_to_coupons_map.put(key, _c_list);
            }else {
                ArrayList<Long> _c_list = new ArrayList<Long>();
                _c_list.add(newCoupon.getCoupon_id());
                _product_to_coupons_map.put(key, _c_list);
            }
        }
    }

    synchronized public void insertOffer(Offer newOffer) {
        if(_offers_map == null) {
            _offers_map = new HashMap<Long, Offer>();
            _product_cat_to_offers_map =
                    new HashMap<Long, ArrayList<Long>>();
        }
        Long key = newOffer.getOffer_id();
        if(!_offers_map.containsKey(key)) {
            _offers_map.put(key, newOffer);
            key = newOffer.getProductCategory_id();
            if(_product_cat_to_offers_map.containsKey(key)) {
                ArrayList<Long> _o_list = _product_cat_to_offers_map.get(key);
                _o_list.add(newOffer.getOffer_id());
                _product_cat_to_offers_map.remove(key);
                _product_cat_to_offers_map.put(key, _o_list);
            }else {
                ArrayList<Long> _o_list = new ArrayList<Long>();
                _o_list.add(newOffer.getOffer_id());
                _product_cat_to_offers_map.put(key, _o_list);
            }
        }
    }

    synchronized public void removeCoupon(long couponId) {
        Coupon _c;
        Long key = new Long(couponId);
        if(_coupons_map != null && _coupons_map.containsKey(key)) {
            _c = (Coupon) _coupons_map.get(key);
            _coupons_map.remove(key);
            Long product = new Long(_c.getCoupon_id());
            ArrayList<Long> _c_list =
                    (ArrayList<Long>) _product_to_coupons_map.get(product);
            _c_list.remove(key);
            _product_to_coupons_map.remove(product);
            _product_to_coupons_map.put(product, _c_list);
        }
    }

    synchronized public void removeOffer(long offerId) {
        Offer _o;
        Long key = new Long(offerId);
        if(_offers_map != null && _offers_map.containsKey(key)) {
            _o = (Offer) _offers_map.get(key);
            _offers_map.remove(key);
            Long product = new Long(_o.getOffer_id());
            ArrayList<Long> _o_list =
                    (ArrayList<Long>) _product_cat_to_offers_map.get(product);
            _o_list.remove(key);
            _product_cat_to_offers_map.remove(product);
            _product_cat_to_offers_map.put(product, _o_list);
        }
    }

    synchronized public Coupon getCoupon(long CouponID) {
        Long key = new Long(CouponID);
        if(_coupons_map != null && _coupons_map.containsKey(key)) {
            Coupon _c = (Coupon) _coupons_map.get(key);
            Date _now = new Date();
            if(_now.compareTo(_c.getDateTo()) > 0) {
                this.removeCoupon(CouponID);
                return null;
            }
            return (Coupon) _coupons_map.get(key);
        }else
            return null;
    }

    synchronized public Offer getOffer(long OfferID) {
        Long key = new Long(OfferID);
        if(_offers_map != null && _offers_map.containsKey(key)) {
            Offer _o = (Offer) _offers_map.get(key);
            Date _now = new Date();
            if(_now.compareTo(_o.getDateTo()) > 0) {
                this.removeOffer(OfferID);
                return null;
            }
            return (Offer) _offers_map.get(key);
        }else
            return null;
    }

    synchronized public ArrayList<Long> getCoupons(long ProductID) {
        Long key = new Long(ProductID);
        if(_product_to_coupons_map != null && _product_to_coupons_map.containsKey(key))
        {
            ArrayList<Long> _c_list = 
                    (ArrayList<Long>) _product_to_coupons_map.get(key);
            Iterator itr = _c_list.iterator();
            while(itr.hasNext()) {
                 Long l = (Long) itr.next();
                 if(this.getCoupon(l.longValue()) == null)
                     _c_list.remove(l.intValue());
            }
            _product_to_coupons_map.remove(key);
            _product_to_coupons_map.put(key, _c_list);
            return _c_list;
        }else
            return null;
    }

    synchronized public ArrayList<Long> getOffers(long ProductID) {
        Long key = new Long(ProductID);
        if(_product_cat_to_offers_map != null &&
                _product_cat_to_offers_map.containsKey(key)) {
            ArrayList<Long> _o_list = _product_cat_to_offers_map.get(key);
            Iterator itr = _o_list.iterator();
            while(itr.hasNext()) {
                Long l = (Long) itr.next();
                if(this.getOffer(l.longValue()) == null)
                    _o_list.remove(l.intValue());
            }
            _product_cat_to_offers_map.remove(key);
            _product_cat_to_offers_map.put(key, _o_list);
            return _o_list;
        }else
            return null;
    }

    synchronized public HashMap<Long, Coupon> getCoupons_map() {
        return _coupons_map;
    }

    synchronized public void setCoupons_map(HashMap<Long, Coupon> _coupons_map) {
        this._coupons_map = _coupons_map;
    }

    synchronized public static long getCreation_time() {
        return _creation_time;
    }

    synchronized public void cleanup_offers() {
        if(_product_cat_to_offers_map != null) {
            Set _offers_key_set = _product_cat_to_offers_map.keySet();
            Iterator itr = _offers_key_set.iterator();
            while(itr.hasNext()) {
                Long l = (Long) itr.next();
                this.getOffers(l.longValue());
            }
        }
    }

    synchronized public void cleanup_coupons() {
        if(_product_to_coupons_map != null) {
            Set _coupons_key_set = _product_to_coupons_map.keySet();
            Iterator itr = _coupons_key_set.iterator();
            while(itr.hasNext()) {
                Long l = (Long) itr.next();
                this.getCoupons(l.longValue());
            }
        }
    }
}

问题是,当我将上面的应用程序(其名称为ETL_Procedures)部署到Apache时,我会得到以下严重的日志条目:

代码语言:javascript
复制
SEVERE: The web application [/ETL_Procedures] appears to have started a thread named [maintenance-task-executor-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Oct 03, 2012 5:35:03 PM org.apache.catalina.loader.WebappClassLoadercheckThreadLocalMapForLeaks
SEVERE: The web application [/ETL_Procedures] created a ThreadLocal with key of type [org.glassfish.gmbal.generic.OperationTracer$1] (value [org.glassfish.gmbal.generic.OperationTracer$1@4c24821]) and a value of type [java.util.ArrayList] (value [[]]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Oct 03, 2012 5:35:03 PM org.apache.catalina.loader.WebappClassLoadercheckThreadLocalMapForLeaks
SEVERE: The web application [/ETL_Procedures] created a ThreadLocal with key of type [com.sun.xml.bind.v2.ClassFactory$1] (value [com.sun.xml.bind.v2.ClassFactory$1@6f0d70f7]) and a value of type [java.util.WeakHashMap] (value [{class com.sun.xml.ws.runtime.config.TubeFactoryList=java.lang.ref.WeakReference@5b73a116, class javax.xml.bind.annotation.adapters.CollapsedStringAdapter=java.lang.ref.WeakReference@454da42, class com.sun.xml.ws.runtime.config.MetroConfig=java.lang.ref.WeakReference@5ec52546, class com.sun.xml.ws.runtime.config.TubeFactoryConfig=java.lang.ref.WeakReference@61124745, class java.util.ArrayList=java.lang.ref.WeakReference@770534cc, class com.sun.xml.ws.runtime.config.Tubelines=java.lang.ref.WeakReference@76cd7a1f, class javax.xml.bind.annotation.W3CDomHandler=java.lang.ref.WeakReference@2c0cc628, class com.sun.xml.ws.runtime.config.TubelineDefinition=java.lang.ref.WeakReference@7aa582af}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Oct 03, 2012 5:35:03 PM org.apache.catalina.loader.WebappClassLoadercheckThreadLocalMapForLeaks
SEVERE: The web application [/ETL_Procedures] created a ThreadLocal with key of type [com.sun.xml.bind.v2.runtime.Coordinator$1] (value [com.sun.xml.bind.v2.runtime.Coordinator$1@826ee11]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@33d7a245]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Oct 03, 2012 5:35:03 PM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/ETL_Procedures] created a ThreadLocal with key of type [org.glassfish.gmbal.generic.OperationTracer$1] (value [org.glassfish.gmbal.generic.OperationTracer$1@4c24821]) and a value of type [java.util.ArrayList] (value [[]]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

我真的不知道是什么导致了那些记忆泄漏。我的问题如下:

  1. 有人能怀疑我的web服务有什么问题吗?如果内存泄漏的原因是Singleton对象,那么我还能做什么来满足我的应用程序需求并避免内存泄漏。
  2. 我是否可以使用任何工具来监视我的线程,以及导致这些严重消息的确切原因是什么?
  3. 如果我让我的应用程序部署了很长时间,我就会得到一个带有以下消息的IllegalStateException: 信息:非法访问:此web应用程序实例已经停止。无法加载com.sun.xml.ws.rx.rm.localization.LocalizationMessages.最终的堆栈跟踪是由为调试目的抛出的错误以及试图终止导致非法访问的线程而引起的,没有功能影响。org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1600),org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559),com.sun.xml.ws.rx.rm.runtime.sequence.SequenceMaintenanceTask.run(SequenceMaintenanceTask.java:81),com.sun.xml.ws.commons.DelayedTaskManager$Worker.run(DelayedTaskManager.java:91),java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471),java.util.concurrent.FutureTask$Sync.innerRun(java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722)

如何才能看到导致此异常的整个调用路径?

谢谢你抽出时间,我真的很抱歉给你这么长时间的留言。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-04 09:50:17

看起来您在重新部署应用程序时获得了java.lang.IllegalStateException,但未能取消部署,一些旧进程仍在运行。也许当您重新部署应用程序时,当其他线程离开synchronization块时,一些线程正在等待。也许这是一个预定的过程,你有吗?很难说是什么。

我可以建议您在web.xml和contextDestroyed()方法中注册侦听器,清理所有资源。并运行一些内存分析工具,例如,垫子

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12722936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档