Программно вычислите память, занятую Объектом Java включая объекты, на которые она ссылается [копируют]

Шаг 2. Удаление клиента

Аутентификация с помощью Azure Active Directory на powershell

Команды AzureAD [ 119]

a) connect-AzureAD -tenantid Azure Active Directory -> Свойства -> ID каталога

b) Get-AzureADApplication -> (+)

Для каждого приложения: [ 1112]

Remove-AzureADApplication -objectid -> (+)

затем:

Remove-AzureADServicePrincipal -ObjectId

Azure Active Directory -> Удалить каталог -> Приложения Exterprise

Для каждого приложения Exterprise: нажмите на строку -> скопировать ID объекта =

в) В моем случае я смог удалить каталоги (арендаторы) после а) и б )

18
задан Cœur 15 April 2017 в 19:20
поделиться

3 ответа

Для этого вам нужно будет использовать отражение . Полученный фрагмент кода слишком сложен для меня, чтобы публиковать его здесь (хотя он скоро будет доступен как часть инструментария GPL, который я создаю), но основная идея такова:

  • Заголовок объекта использует 8 байтов (для указателя класса и счетчик ссылок)
  • Каждое примитивное поле использует 1, 2, 4 или 8 байтов в зависимости от фактического типа
  • Каждое поле ссылки на объект (т. е. не примитивное) использует 4 байта (ссылку, плюс все, что использует объект ссылки

Вам нужно обрабатывать массивы отдельно (8 байтов заголовка, 4 байта поля длины, 4 * байта таблицы длины, плюс все, что используются внутри объектов). Вам нужно обрабатывать другие типы объектов, перебирая поля (и это родительские поля), используя отражение.

11
ответ дан 30 November 2019 в 08:59
поделиться

Похоже, что для этого уже есть утилита под названием Classmexer .

Я сам не пробовал, но я бы пошел по этому пути, прежде чем я свернул сам.

6
ответ дан 30 November 2019 в 08:59
поделиться

Хорошим общим решением является использование дельты размера кучи. Это требует минимальных усилий и может использоваться повторно для любого типа графа объекта / объекта. Создавая и уничтожая ваши объекты много раз и собирая мусор между ними, а затем беря среднее значение, вы избегаете оптимизаций компилятора и JVM, которые изменяют результаты и получают довольно точный результат. Если вам нужен точный ответ вплоть до байта, то это может не быть решением для вас, но для всех известных мне практических приложений (профилирование, расчеты требований к памяти) он работает очень хорошо. Код ниже сделает именно это.

    public class Sizeof {
      public static void main(String[] args)
          throws Exception {
        // "warm up" all classes/methods that we are going to use:
        runGC();
        usedMemory();

        // array to keep strong references to allocated objects:
        final int count = 10000; // 10000 or so is enough for small ojects
        Object[] objects = new Object[count];

        long heap1 = 0;

        // allocate count+1 objects, discard the first one:
        for (int i = -1; i < count; ++i) {
          Object object;

    //// INSTANTIATE YOUR DATA HERE AND ASSIGN IT TO 'object':


          object=YOUR OBJECT;
    ////end your code here
          if (i >= 0) {
            objects[i] = object;
          }
          else {
            object = null; // discard the "warmup" object
            runGC();
            heap1 = usedMemory(); // take a "before" heap snapshot
          }
        }

        runGC();
        long heap2 = usedMemory(); // take an "after" heap snapshot:

        final int size = Math.round(((float)(heap2 - heap1)) / count);
        System.out.println("'before' heap: " + heap1 +
                           ", 'after' heap: " + heap2);
        System.out.println("heap delta: " + (heap2 - heap1) +
                           ", {" + objects[0].getClass() + "} size = " + size + " bytes");
      }

      // a helper method for creating Strings of desired length
      // and avoiding getting tricked by String interning:
      public static String createString(final int length) {
        final char[] result = new char[length];
        for (int i = 0; i < length; ++i) {
          result[i] = (char)i;
        }

        return new String(result);
      }

      // this is our way of requesting garbage collection to be run:
      // [how aggressive it is depends on the JVM to a large degree, but
      // it is almost always better than a single Runtime.gc() call]
      private static void runGC()
          throws Exception {
        // for whatever reason it helps to call Runtime.gc()
        // using several method calls:
        for (int r = 0; r < 4; ++r) {
          _runGC();
        }
      }

      private static void _runGC()
          throws Exception {
        long usedMem1 = usedMemory(), usedMem2 = Long.MAX_VALUE;

        for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++i) {
          s_runtime.runFinalization();
          s_runtime.gc();
          Thread.currentThread().yield();

          usedMem2 = usedMem1;
          usedMem1 = usedMemory();
        }
      }

      private static long usedMemory() {
        return s_runtime.totalMemory() - s_runtime.freeMemory();
      }

      private static final Runtime s_runtime = Runtime.getRuntime();

    } // end of class
3
ответ дан 30 November 2019 в 08:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: