Java 如何在运行时查找堆/堆栈中对象的强引用数
团队 在java中,是否有可能知道一个对象当前有多少活动/强引用 例如在下面的代码中;类的对象可以由项目中的许多类持有。但我想在监视器线程中打印它Java 如何在运行时查找堆/堆栈中对象的强引用数,java,c,garbage-collection,heap-memory,Java,C,Garbage Collection,Heap Memory,团队 在java中,是否有可能知道一个对象当前有多少活动/强引用 例如在下面的代码中;类的对象可以由项目中的许多类持有。但我想在监视器线程中打印它 public class A { public static A a = new A(); public static A getInstance() { return a; } private A() { new Monitor(this).start(); } class Monitor exte
public class A {
public static A a = new A();
public static A getInstance() {
return a;
}
private A() {
new Monitor(this).start();
}
class Monitor extends Thread {
A refA;
public Monitor(A ref) {
this.refA = ref;
}
public void run () {
//TODO Print how many references currently available for Object A referenced by refA;
//Sure It will be minimum one. (which is "a" in this class A)
}
}
}
请不要太重视这个示例程序。我的问题是如何找到堆/堆栈中一个对象有多少强引用?唯一的好处是,我们手头有一个关于这个对象的强有力的参考
如果在java中不可能;我可以把这个强引用传递给C语言吗;从C语言我能做到这一点吗
我只是想知道探查器/工具是如何做到这一点的?
请提供帮助。不,如果不更改虚拟机上的类或分支工具,您将无法获得准确的计数。由于对性能的影响,虚拟机上的类或分支工具很难在生产中生成
使用,您可以在对象即将被丢弃并在此时执行操作时收到通知,但没有可用的计数,也不总是由虚拟机处理。不,如果不更改虚拟机上的类或分支工具,您将无法获得准确的计数,因为这会影响性能
使用,您可以在对象即将被丢弃并在此时执行操作时收到通知,但没有可用的计数,也不总是由VM处理。您可以执行堆转储并对其进行分析,以找到对任何对象的引用数 您对此有什么要求,以及您将如何处理这些信息,因为我认为有一种更容易/更好的方法来实现您的目标 基于WeakHashMap
/**
* Reference queue for cleared WeakEntries
*/
private final ReferenceQueue<Connection> queue = new ReferenceQueue<>();
List<WeakReference<Connection>> usedConnections = ....
// when you have a new connection
Connection connection = ....
usedConnections.add(new WeakReference(connection, queue));
// checking the queue for discarded objects.
// remove null references from usedConnections
for (Connection x; (x = queue.poll()) != null; ) {
synchronized (queue) {
x.close();
}
}
您可以执行堆转储并对其进行分析,以找到对任何对象的引用数 您对此有什么要求,以及您将如何处理这些信息,因为我认为有一种更容易/更好的方法来实现您的目标 基于WeakHashMap
/**
* Reference queue for cleared WeakEntries
*/
private final ReferenceQueue<Connection> queue = new ReferenceQueue<>();
List<WeakReference<Connection>> usedConnections = ....
// when you have a new connection
Connection connection = ....
usedConnections.add(new WeakReference(connection, queue));
// checking the queue for discarded objects.
// remove null references from usedConnections
for (Connection x; (x = queue.poll()) != null; ) {
synchronized (queue) {
x.close();
}
}
你可以试试这样的东西
Class A
{
static int instanceCount = 0;
public A()
{
instanceCount++;
}
protected finalize()
{
instanceCount--;
}
public static int getInstanceCount()
{
return instanceCount;
}
}
我相信这是使用代码最接近于包含类引用的方法。希望对你有所帮助……你可以试试这样的东西
Class A
{
static int instanceCount = 0;
public A()
{
instanceCount++;
}
protected finalize()
{
instanceCount--;
}
public static int getInstanceCount()
{
return instanceCount;
}
}
我相信这是使用代码最接近于包含类引用的方法。希望对您有所帮助…为什么要在运行时查找java中一个对象的引用数?我想在调用getInstance后只有一个活动引用时执行一些操作。表示getInstance的调用方方法在堆栈中结束。因此,我们只有一个活动引用是“a”。看起来您更需要某种方面的功能,请尝试AspectJ或Spring AOP。您只需要上侧面还是两者都需要?我的意思是,当计数从0变为1时,你需要做一次1,每次计数从0变为1,每次计数从X变为3=1对1?为什么要在运行时查找java中一个对象的引用数?我想在调用getInstance后只有一个活动引用时执行一些操作。表示getInstance的调用方方法在堆栈中结束。因此,我们只有一个活动引用是“a”。看起来您更需要某种方面的功能,请尝试AspectJ或Spring AOP。您只需要上侧面还是两者都需要?我的意思是,当计数从0变为1时,你需要做一次1,每次计数从0变为1,每次计数从X变为3=1到1?池中请求的代码数据库连接对象中约700个位置;但他们从未关门。这是不可见的,因为最大无连接大小为75。仅在负载测试期间发现。我只想要解决方案,而不是对所有文件进行代码更改;我怎样才能关闭它池边本身?听起来你有内存泄漏。我会使用内存分析器来查看它们被保留在哪里。您是否像PreparedStatements一样关闭JDBC资源?该代码从未关闭过连接,甚至连一个地方都没有。所以现在很难换到这700个地方。那么,有什么建议可以纠正这个问题吗?可以通过不使用连接清理资源来保持连接的开放性。真正的修复方法是修复代码。任何变通方法都不可能像您认为的那样有效,因为仅仅关闭连接是不够的。所有这些地方都正确关闭了语句和结果集。但连接未关闭或未返回到池。有一件事我可以说,一旦事务块结束,引用可能会结束,但不会被释放。因此,在GC之前,我从max conn到达的池中获得异常。因此,如果没有对这个conn对象的活动引用,我想通过监视器线程关闭/返回池。但如何从池中请求的代码数据库连接对象中约700个位置;但他们从未关门。这是不可见的,因为最大无连接大小为75。仅在负载测试期间发现。我只是想要解决方案,而不是进行代码更改
在所有档案上;我怎样才能关闭它池边本身?听起来你有内存泄漏。我会使用内存分析器来查看它们被保留在哪里。您是否像PreparedStatements一样关闭JDBC资源?该代码从未关闭过连接,甚至连一个地方都没有。所以现在很难换到这700个地方。那么,有什么建议可以纠正这个问题吗?可以通过不使用连接清理资源来保持连接的开放性。真正的修复方法是修复代码。任何变通方法都不可能像您认为的那样有效,因为仅仅关闭连接是不够的。所有这些地方都正确关闭了语句和结果集。但连接未关闭或未返回到池。有一件事我可以说,一旦事务块结束,引用可能会结束,但不会被释放。因此,在GC之前,我从max conn到达的池中获得异常。因此,如果没有对这个conn对象的活动引用,我想通过监视器线程关闭/返回池。但如何希望您知道一旦getInstance调用方方法代码块结束,引用就会结束。它永远不会与运行时调用的getInstance数量相同。此外,我们也无法从finalize获得帮助,因为我们正在讨论活动对象的引用。在上面的示例中,一个类加载器的实例计数始终为1。现在在JVM中,即使是由不同类加载器加载的相同类也被视为不同的类。因此,在您的例子中,实例数=加载类A的类加载器数。希望您知道一旦getInstance调用方方法代码块结束,引用将结束。它永远不会与运行时调用的getInstance数量相同。此外,我们也无法从finalize获得帮助,因为我们正在讨论活动对象的引用。在上面的示例中,一个类加载器的实例计数始终为1。现在在JVM中,即使是由不同类加载器加载的相同类也被视为不同的类。因此,在您的例子中,实例的数量=加载类A的类装入器的数量。您能告诉我探查器/工具的功能吗?用C语言可以吗?那个么我可以使用本机调用吗?在不严重影响性能的情况下,您无法做到这一点,因为现代JVM甚至不记录实例数。谢谢。你能为我和彼得·劳瑞的转换提供一些建议吗?好的。您能告诉我探查器/工具的功能吗?用C语言可以吗?那个么我可以使用本机调用吗?在不严重影响性能的情况下,您无法做到这一点,因为现代JVM甚至不记录实例数。谢谢。你能为我和彼得·劳瑞的转换提供一些建议吗?