0


I'm working on a maintenance project and a issue is raised for memory leak.

Basically the code is to load the values of data in application context from database. If the values in DB is changed then this functionality is used to update the value in application context also without restarting the server.

The variables annotated with @Value annotation are updated every where in the project, eg:

@Value("${cost}")
private String cost;

The method where memory leak is reported by production is updateObjects():

public class DbPropertySourcesPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

   private CustomBeanPostProcessor customBeanPostProcessor;
   private static Properties dbProps = new Properties();

 private void updateObjects() {
  for (String key : customBeanPostProcessor.getObjectMap().keySet()) {
     if (null != dbProps.get(key)) {
        List<Object> objectList = customBeanPostProcessor.getObjectMap().get(key);
        if (objectList != null && objectList.size() > 0) {
           for (Object object : objectList) {
              if (null != object) {
                 for (Field field : object.getClass().getDeclaredFields()) {
                    Value value = field.getAnnotation(Value.class);
                    if (null != value && null != value.value()
                          && value.value().replace("${", "").replace("}", "").length() > 0
                          && value.value().replace("${", "").replace("}", "").equalsIgnoreCase(key)
                          && field.getType() == String.class) {
                       field.setAccessible(true);
                       try {
                          field.set(object, dbProps.get(key));
                       }
                       catch (IllegalAccessException ee) {
                          logger.error("Unable to update Object",ee);
                       }
                    }
                 }
              }
           }
        }
     }
  }
 }

Is it because of reflection used & can reflectionUtils of spring solve the problem?

CustomBeanPostProcessor.java

public class CustomBeanPostProcessor implements BeanPostProcessor {

public static Map<String, ArrayList<Object>> objectMap;

public Object postProcessBeforeInitialization(Object o, String string) throws BeansException {
    return(o);
}
  public Object postProcessAfterInitialization(Object o, String string) throws BeansException {
    if(objectMap == null) {
           objectMap = new HashMap<String, ArrayList<Object>>();
    }
     if(null == o) {
         return(o);
     }
     if(AopUtils.isAopProxy(o) && o instanceof Advised) {
                  Class targetClass = ((Advised)o).getTargetClass();
                    Object object =  null;
                  try {
                        Object target = ((Advised)o).getTargetSource().getTarget();
                        object = targetClass.cast(target);
                for(Field field:object.getClass().getDeclaredFields()) {
                    Value value = field.getAnnotation(Value.class);
                    if(null != value && null != value.value() && value.value().replace("${", "").replace("}", "").length() > 0) {
                        updateObjectMap(value.value().replace("${", "").replace("}", ""), object);
                    }
                }
                  }
                  catch(Exception ex) {
                        ex.printStackTrace();
                  }
     }
     else {
         for(Field field:o.getClass().getDeclaredFields()) {
             Value value = field.getAnnotation(Value.class);
             if(null != value && null != value.value() && value.value().replace("${", "").replace("}", "").length() > 0) {
                 updateObjectMap(value.value().replace("${", "").replace("}", ""), o);
             }
         }
     }
     return(o);
 }




public static void updateObjectMap(String key, Object object) {
    ArrayList<Object> objectList = objectMap.get(key);
    if(null == objectList) {
        objectList = new ArrayList<Object>();
        objectList.add(object);
        objectMap.put(key, objectList);
    }
    else {
        objectList.add(object);
    }
}

public Map<String, ArrayList<Object>> getObjectMap() {
    return objectMap;
}

public void setObjectMap(Map<String, ArrayList<Object>> objectMap) {
    this.objectMap = objectMap;
}
}

Please let me know if more information is required.
Thank You.

Droy
  • 173
  • 2
  • 17
  • Possible duplicate of [How to find a Java Memory Leak](http://stackoverflow.com/questions/40119/how-to-find-a-java-memory-leak) – Jiri Tousek Nov 24 '16 at 07:55
  • Actually not, I'm looking for a solution in the above code to remove the memory leak. The solution may include replacing the use of java reflection with spring reflectionutils, or maybe some other way – Droy Nov 24 '16 at 09:15
  • If you are indeed already looking for the way to remove the leak, not still trying to find it, you should describe in the question why and how exactly does the leak occur. You must first completely understand the leak before you can fix it. – Jiri Tousek Nov 24 '16 at 09:41
  • In my case I'm looking for both finding & removing but specifically for the scenario provided, & my comment was in the response of your comment "Possible duplicate...." because I don't find a solution there either. and I've mentioned the method in which the memory leak issue is occuring – Droy Nov 24 '16 at 09:49
  • The first step is to identify the leak exactly - that's why I believe it's duplicate. To identify the leak, that question has some good advice. Once you identify the leak, you either will see clearly how to fix it or you will be able to provide more specific info in an update to this question. – Jiri Tousek Nov 24 '16 at 09:53
  • It's not enough to know the leak occurs in the method. You need to know what data are leaking, and why are they not garbage-collected (i.e. know the path from the leaking data to a garbage-collection root). – Jiri Tousek Nov 24 '16 at 09:55

0 Answers0