changeset 54:296461a953ac

Bug 2378: JVM may crashe when class unload is occurred. reviewed-by: ykubota
author Yasumasa Suenaga <yasuenag@gmail.com>
date Sun, 24 May 2015 18:31:15 +0900
parents f2b28c124605
children bf062115601d
files agent/ChangeLog agent/src/classContainer.cpp agent/src/classContainer.hpp agent/src/snapShotMain.cpp agent/src/snapShotProcessor.cpp
diffstat 5 files changed, 67 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ChangeLog	Fri May 22 11:58:27 2015 +0900
+++ b/agent/ChangeLog	Sun May 24 18:31:15 2015 +0900
@@ -1,3 +1,7 @@
+2015-05-24 Yasumasa Suenaga  <yasuenag@gmail.com>
+
+	* Bug 2378: JVM may crashe when class unload is occurred.
+
 2015-05-22 KUBOTA Yuji  <kubota.yuji@lab.ntt.co.jp>
 
 	* Bug 2376: Deadlock finder needs to return a original _thread_state to HotSpot VM.
--- a/agent/src/classContainer.cpp	Fri May 22 11:58:27 2015 +0900
+++ b/agent/src/classContainer.cpp	Sun May 24 18:31:15 2015 +0900
@@ -1,7 +1,7 @@
 /*!
  * \file classContainer.cpp
  * \brief This file is used to add up using size every class.
- * Copyright (C) 2011-2013 Nippon Telegraph and Telephone Corporation
+ * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -88,7 +88,7 @@
  * \brief TClassContainer constructor.
  */
 TClassContainer::TClassContainer(TClassContainer *base, bool needToClr)
-                                                     : classContainerInTLS() {
+                                        : classContainerInTLS(), pendingQueue(){
   
   try {
 
@@ -113,6 +113,7 @@
   lockval = 0;
   tlsLock = 0;
   needToClear = needToClr;
+  pendingQueueLock = 0;
 }
 
 /*!
@@ -290,6 +291,27 @@
     classMap->clear();
   }
   SpinLockRelease(&lockval);
+
+  SpinLockWait(&pendingQueueLock);
+  {
+    pendingQueue.clear();
+  }
+  SpinLockRelease(&pendingQueueLock);
+
+}
+
+/*!
+ * \brief Remove all object data in pending queue.
+ */
+void TClassContainer::removePendingObjectData(void){
+  SpinLockWait(&pendingQueueLock);
+  {
+    while(!pendingQueue.empty()){
+      popClass(pendingQueue.front());
+      pendingQueue.pop_front();
+    }
+  }
+  SpinLockRelease(&pendingQueueLock);
 }
 
 /*!
--- a/agent/src/classContainer.hpp	Fri May 22 11:58:27 2015 +0900
+++ b/agent/src/classContainer.hpp	Sun May 24 18:31:15 2015 +0900
@@ -1,7 +1,7 @@
 /*!
  * \file classContainer.hpp
  * \brief This file is used to add up using size every class.
- * Copyright (C) 2011-2013 Nippon Telegraph and Telephone Corporation
+ * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -58,6 +58,11 @@
 typedef std::deque<TClassContainer*> TLocalClassContainer;
 
 /*!
+ * \brief Pending queue for processing unloaded class data.
+ */
+typedef std::deque<TObjectData *> TPendingQueue;
+
+/*!
  * \brief Memory usage alert types.
  */
 typedef enum{
@@ -204,6 +209,12 @@
      * \brief Remove all-class from container.
      */
     void allClear(void);
+
+    /*!
+     * \brief Remove all object data in pending queue.
+     */
+    void removePendingObjectData(void);
+
     /*!
      * \brief Output all-class information to file.
      * \param snapshot [in] Snapshot instance.
@@ -211,6 +222,17 @@
      */
     virtual TSorter<THeapDelta> *afterTakeSnapShot(TSnapShotContainer *snapshot);
 
+    /*!
+     * \brief Push unloaded object data to pending queue.
+     */
+    inline void pushToPendingQueue(TObjectData *data){
+      SpinLockWait(&pendingQueueLock);
+      {
+        pendingQueue.push_back(data);
+      }
+      SpinLockRelease(&pendingQueueLock);
+    }
+
   protected:
     /*!
      * \brief ClassContainer in TLS of each threads.
@@ -248,6 +270,16 @@
      */
     bool needToClear;
 
+    /*!
+     * \brief Pending queue for processing unloaded class data.
+     */
+    TPendingQueue pendingQueue;
+
+    /*!
+     * \brief SpinLock variable for pending queue.
+     */
+    int pendingQueueLock;
+
 };
 
 #endif // CLASS_CONTAINER_HPP
--- a/agent/src/snapShotMain.cpp	Fri May 22 11:58:27 2015 +0900
+++ b/agent/src/snapShotMain.cpp	Sun May 24 18:31:15 2015 +0900
@@ -1,7 +1,7 @@
 /*!
  * \file snapShotMain.cpp
  * \brief This file is used to take snapshot.
- * Copyright (C) 2011-2013 Nippon Telegraph and Telephone Corporation
+ * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -162,8 +162,8 @@
     TObjectData *counter = clsContainer->findClass(klassOop);
       
     if (likely(counter != NULL)) {
-      /* Remove class data. */
-      clsContainer->popClass(counter);
+      /* Push to remove pending queue. */
+      clsContainer->pushToPendingQueue(counter);
     }
 
   }
--- a/agent/src/snapShotProcessor.cpp	Fri May 22 11:58:27 2015 +0900
+++ b/agent/src/snapShotProcessor.cpp	Sun May 24 18:31:15 2015 +0900
@@ -1,7 +1,7 @@
 /*!
  * \file snapShotProcessor.cpp
  * \brief This file is used to output ranking and call snapshot function.
- * Copyright (C) 2011-2013 Nippon Telegraph and Telephone Corporation
+ * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -119,6 +119,7 @@
       
       /* If output failure. */
       if (unlikely(ranking == NULL)) {
+        controller->_container->removePendingObjectData();
         TSnapShotContainer::releaseInstance(snapshot);
         continue;
       }
@@ -129,6 +130,7 @@
       }
       
       /* Clean up. */
+      controller->_container->removePendingObjectData();
       TSnapShotContainer::releaseInstance(snapshot);
       delete ranking;
       ranking = NULL;