上一篇



在Java中输出对象个数,可通过静态计数器实现:在类中定义
static int count,构造方法中
count++,析构方法中
count--,调用
类名.count即可输出当前对象数量。
<div class="article-content">
<p>在Java编程中,统计对象的创建数量是调试和性能分析的重要技能,以下是<strong>四种实用方法</strong>及其实现代码:</p>
<h3>方法1:静态计数器(基础版)</h3>
<pre><code class="language-java">public class User {
// 声明静态计数器
private static int instanceCount = 0;
public User() {
// 每次创建对象时计数器+1
instanceCount++;
}
// 获取对象数量的公共方法
public static int getInstanceCount() {
return instanceCount;
}
public static void main(String[] args) {
new User();
new User();
System.out.println("当前对象数: " + User.getInstanceCount()); // 输出:2
}
}</code></pre>
<p><strong>特点:</strong>简单高效,适合单线程环境</p>
<h3>方法2:线程安全计数器</h3>
<pre><code class="language-java">public class Product {
// 使用AtomicInteger保证线程安全
private static AtomicInteger atomicCount = new AtomicInteger(0);
public Product() {
atomicCount.incrementAndGet();
}
// 工厂方法统计对象创建
public static Product createInstance() {
return new Product();
}
public static int getTotalCount() {
return atomicCount.get();
}
public static void main(String[] args) {
IntStream.range(0, 100).parallel().forEach(i -> Product.createInstance());
System.out.println("多线程创建数量: " + Product.getTotalCount()); // 输出:100
}
}</code></pre>
<p><strong>优势:</strong>支持高并发场景,避免计数错误</p>
<h3>方法3:引用队列监控(高级)</h3>
<pre><code class="language-java">public class AdvancedCounter {
private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue<>();
private static final Set<WeakReference<Object>> REFERENCES = new HashSet<>();
private static int totalCreated = 0;
public static <T> T track(T obj) {
REFERENCES.add(new WeakReference<>(obj, QUEUE));
totalCreated++;
cleanQueue();
return obj;
}
private static void cleanQueue() {
while (QUEUE.poll() != null) {
// 当对象被GC回收时自动移出
}
}
// 获取存活对象数
public static int getActiveCount() {
cleanQueue();
return (int) REFERENCES.stream().filter(ref -> ref.get() != null).count();
}
// 获取历史创建总数
public static int getTotalCreated() {
return totalCreated;
}
}
// 使用示例
Object obj = AdvancedCounter.track(new Object());
System.gc();
System.out.println("存活对象数: " + AdvancedCounter.getActiveCount());</code></pre>
<p><strong>应用场景:</strong>内存泄漏检测、对象生命周期监控</p>
<h3>方法4:Java Agent字节码增强(生产环境)</h3>
<p>通过<code>java.lang.instrument</code>在类加载时注入计数代码:</p>
<pre><code class="language-java">public class ObjectCounterAgent {
public static void premain(String args, Instrumentation inst) {
inst.addTransformer((loader, className, classBeingRedefined,
protectionDomain, classfileBuffer) -> {
ClassReader reader = new ClassReader(classfileBuffer);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
reader.accept(new ClassVisitor(Opcodes.ASM9, writer) {
@Override
public MethodVisitor visitMethod(int access, String name,
String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if ("<init>".equals(name)) {
return new MethodVisitor(Opcodes.ASM9, mv) {
@Override
public void visitInsn(int opcode) {
if (opcode == Opcodes.RETURN) {
visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
visitLdcInsn("对象已创建! 总数: " + ++Counter.total);
visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
}
super.visitInsn(opcode);
}
};
}
return mv;
}
}, 0);
return writer.toByteArray();
});
}
static class Counter {
static long total = 0;
}
}</code></pre>
<p><strong>启动参数:</strong><code>-javaagent:agent.jar</code></p>
<h3>使用建议</h3>
<div class="recommendation">
<ul>
<li><strong>简单项目</strong> → 选择静态计数器(方法1)</li>
<li><strong>并发系统</strong> → 采用线程安全计数器(方法2)</li>
<li><strong>性能调优</strong> → 使用引用队列监控(方法3)</li>
<li><strong>生产环境</strong> → Java Agent方案(方法4)</li>
</ul>
</div>
<h3>注意事项</h3>
<div class="warning-block">
<ol>
<li><code>finalize()</code>方法已被废弃,不要依赖它做计数递减</li>
<li>对象回收受JVM垃圾收集策略影响,存活计数存在延迟</li>
<li>生产环境推荐结合JMX或Micrometer暴露计数指标</li>
</ol>
</div>
<div class="conclusion">
<p>根据需求选择合适方案:开发阶段用静态计数器快速验证,生产环境用Java Agent无侵入监控,关键业务建议同时记录对象创建堆栈信息,便于问题溯源。</p>
</div>
</div>
<style>
.article-content {
font-family: 'Segoe UI', Tahoma, sans-serif;
line-height: 1.6;
color: #333;
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
h3 {
color: #2c3e50;
border-bottom: 2px solid #3498db;
padding-bottom: 6px;
margin-top: 25px;
}
pre {
background: #f8f9fa;
border-left: 4px solid #2980b9;
padding: 15px;
overflow: auto;
border-radius: 0 4px 4px 0;
}
code {
font-family: 'Fira Code', Consolas, monospace;
font-size: 14px;
}
.recommendation {
background: #e8f4fd;
border: 1px solid #bbdefb;
padding: 15px;
border-radius: 4px;
margin: 15px 0;
}
.warning-block {
background: #fff8e1;
border: 1px solid #ffecb3;
padding: 15px;
border-radius: 4px;
margin: 15px 0;
}
.conclusion {
background: #e8f5e9;
border: 1px solid #c8e6c9;
padding: 15px;
border-radius: 4px;
margin-top: 20px;
}
ul, ol {
margin: 10px 0;
}
</style>
<!-- 引用说明 -->
<footer>
本文技术要点基于Oracle官方文档及《Effective Java》实践建议,引用ASM字节码操作库实现高级监控方案。
</footer>
