В приложении Groovy тысячи экземпляров NumberAwareComparator?

#memory #groovy

#память #groovy

Вопрос:

Я запускаю приложение с интенсивным вводом-выводом, и когда я запускаю профилировщик jvisualvm, я вижу, что NumberAwareComparator занимает 33% памяти и 55% всех объектов!

Это нормально? Зачем ему это делать? С чего я могу начать искать решение этой проблемы?

/ * более поздняя версия — пример кода*/

 //Using GPars
(0..length - 1).eachParallel { i ->
                def final h = [:]
                distHash[i] = h

                println("Calculating distances ")

                if (i   1 < length - 1) {
                    ((i   1)..length - 1).each {j ->
                        def d = distanceCalc.getDistance(paragraphs[i], paragraphs[j])
                        if (d < 0.25) {
                            h[j] = d
                        }
                    }
                }
            }
  

Спасибо!


Я думаю, у меня есть какое-то объяснение, но я все еще не уверен в механизме. У меня была функция, которая выполняла некоторые базовые числовые вычисления, и когда она запускалась, у меня было множество экземпляров NumberAwareComparator :

 (0..length - 1).eachParallel { i ->
                def final h = [:]
                distHash[i] = h

                println("Calculating distances ")

                if (i   1 < length - 1) {
                    ((i   1)..length - 1).each {j ->
                        def d = distanceCalc.getDistance(paragraphs[i], paragraphs[j])
                        if (d < 0.25) {
                            h[j] = d
                        }
                    }
                }
            }
  

Как только я объявил тип для каждой переменной (следующим образом), все компараторы исчезли и были заменены на floats / ints

 (0..length - 1).eachParallel { i ->
                final LinkedHashMap<Integer, Float> h = new LinkedHashMap<Integer, Float>()
                distHash[i] = h

                println("Calculating distances ")

                if (i   1 < length - 1) {
                    ((i   1)..length - 1).each {j ->
                        float d = distanceCalc.getDistance(paragraphs[i], paragraphs[j])
                        if (d < 0.25) {
                            h[j] = d
                        }
                    }
                }
            }
  

Комментарии:

1. Показывает ли он вам код, который их генерирует? У вас есть пример вашего кода?

Ответ №1:

Похоже, что этот класс, вероятно, не имеет состояния (но вы должны подтвердить это, просмотрев исходный код). Если это так, вы должны иметь возможность безопасно заменить все эти экземпляры одним экземпляром.

Если это приложение Grails, вы можете сделать это, используя что-то вроде следующего в Bootstrap.groovy

 def singleton = new NumberAwareComparator()

NumberAwareComparator.metaClass.constructor << { ->
    singleton
}
  

В качестве альтернативы вы могли бы поместить приведенный выше код в doWithDynamicMethods закрытие плагина Grails.

Если это не приложение Grails, вы можете использовать класс DelegatingMetaClass