A NullReferenceException
бросается, когда мы пытаемся получить доступ к свойствам нулевого объекта или когда значение строки становится пустым, и мы пытаемся получить доступ к строковым методам.
Например:
string str = string.Empty;
str.ToLower(); // throw null reference exception
Public Class Person {
public string Name { get; set; }
}
Person objPerson;
objPerson.Name /// throw Null refernce Exception
Вы можете попробовать:
см. эту (старую) статью для образца.
Вероятно, есть лучшие способы сделать это, используя JPDA или JMX , но я не нашел, как ...
public class NumOfObjects {
static int count=0;
{
count++;
}
public static void main(String[] args)
{
NumOfObjects no1=new NumOfObjects();
System.out.println("no1:" + count);//1
NumOfObjects no2=new NumOfObjects();
System.out.println("no2:"+ count); //2
for (int i=0; i<10;i++)
{
NumOfObjects noi=new NumOfObjects();
}
System.out.println("Total objects:"+count);// 12
}
}
Используйте jvisualvm и выполните выборку памяти. Он покажет количество классов и экземпляров:
[/g1]
Если все ваши объекты созданы с помощью какого-то класса Factory
, вы можете найти количество объектов в куче. Даже тогда вы должны иметь что-то в методе finalize()
. Конечно, это не может быть сделано для всех объектов, например. классы библиотеки jdk не могут быть изменены. Но если вы хотите найти количество экземпляров определенного класса, который вы создали, вы можете найти это.
Самый простой способ - использовать инструмент jmap
. Если вы напечатаете гистограмму объектов в конце, вы увидите общее количество экземпляров, а также накопленный размер всех объектов:
jmap -histo <PID>
напечатает целые объекты с количеством экземпляров и размером. Последняя строка будет содержать общее число
Total 2802946 174459656
Второй столбец - общий счетчик экземпляров, а последний - общие байты.
Для отладки вы можете использовать профилировщик (например, YourKit, коммерческий профилировщик java). Вы найдете как открытые, так и коммерческие варианты профилей java.
Для интеграции с вашим кодом вы можете использовать технику «Аспектно-ориентированное программирование». Рамки AOP (например, AspectWerkz) позволяют изменять файлы классов во время загрузки класса. Это позволит вам модифицировать конструкторы для регистрации объектов в «все-мои-runtime-objects-framework».
class Test1
{
static int count=0;
public Test1()
{
count++;
System.out.println("Total Objects"+" "+count);
}
}
public class CountTotalNumberOfObjects
{
public static void main(String[] args)
{
Test1 t = new Test1();
Test1 t1 = new Test1();
Test1 t3 = new Test1();
Test1 t11 = new Test1();
Test1 t111 = new Test1();
Test1 t13 = new Test1();
}
}
Насколько я знаю, вы не можете. Однако вы можете получить объем памяти, используемый для программы:
Runtime rt = Runtime.getRuntime();
System.out.println("Used: " + (rt.totalMemory() - rt.freeMemory());
System.out.println("Free: " + rt.freeMemory());
System.out.println("Total: " + rt.totalMemory());
public class ObjectCount
{
static int i;
ObjectCount()
{
System.out.println(++i);
}
public static void main(String args[])
{
ObjectCount oc = new ObjectCount();
ObjectCount od = new ObjectCount();
ObjectCount oe = new ObjectCount();
ObjectCount of = new ObjectCount();
ObjectCount og = new ObjectCount();
}
}
jmap - стандартная утилита java, которую вы можете использовать для сбора дампов и статистики кучи. Я не могу сказать, какой протокол используется jmap для подключения к JVM для получения этой информации, и неясно, доступна ли эта информация для программы, запущенной в JVM напрямую (хотя я уверен, что программа может запросить JVM через некоторый сокет, чтобы получить эту информацию).
JVM TI - это интерфейс инструмента, используемый кодом C, и он имеет довольно полный доступ к событиям JVM, но это код C, а не напрямую доступный JVM. Возможно, вы могли бы написать C lib, а затем интерфейс с ним, но нет ничего из этого.
Существует несколько JMX MBeans, но я не думаю, что любой из них предоставляет фактический счет объекта. Вы можете получить статистику памяти из них (это то, что использует JConsole). Изучите классы java.lang.management.
Если вы хотите быстро (легко реализовать, не обязательно быстрый результат, так как jmap занимает некоторое время), я бы отменил запуск jmap, и просто прочитайте полученный файл.