如何在运行时监视某些java方法分配的内存

我正在创建一个java程序,我的类假设A有一些预定义的行为。 但是用户可以覆盖我的class级以改变其行为。 因此,我的脚本将检查是否存在某些子类,而不是我将其称为行为,但如果他在代码中编写了一些阻塞代码或内存泄漏,该怎么办呢。

这可能会损害我的流程。 在java中是否有任何方法来监视某些方法分配的内存。

请建议。

但如果他在他的代码中写了一些阻塞代码或内存韭菜呢?

首先,我建议你好好记录你的课程。 描述允许用户做什么和不做什么。 给用例做什么(如果可能的话)。

对于阻塞代码部分,如果你有一些时序问题,你可以将方法的执行包装在一个Future ,让ExecutorService执行代码。 这样,如果执行花费太多时间,您将能够取消执行。

对于内存泄漏问题,我想你不是在谈论内存泄漏,而是通过调用重写方法引起的内存消耗增加。 java中的内存泄漏毕竟很少见。

您将无法检测方法的内存消耗,这不是java的工作方式。 记忆是全球性的。 如果例如加载了外部库(JNI),或者类路径中的某个库现在将使用更多内存,您会怎么做? 你无法分辨。

除了监控整体内存消耗之外,别无他法(有人请告诉我,如果我错了)。

Oracle有很好的解决内存泄漏问题的文档。 它建议应该使用NetBeans Profiler作为工具。

http://www.oracle.com/technetwork/java/javase/memleaks-137499.html

我相信你可以使用相同的调试API在运行时检查行为不当的代码,但这会带来性能损失,可能类似于用大锤杀死一只苍蝇。 我个人不会让这样的东西在生产中运行。 相反,我会依靠严格的测试和同行评审。

对于外部监视,您可以使用VisualVM或JConsole(JDK的一部分),对于内部您可以使用Runtime类:

 Runtime rt = Runtime.getRuntime(); long totalMem = rt.totalMemory(); long maxMem = rt.maxMemory(); long freeMem = rt.freeMemory(); 

通过Thread类,您可以检查所有线程的状态。 从未直接使用它,因为应用程序服务器或批处理API正在完成它们的工作……所以,我不需要重新发明轮子。 我建议使用像VisualVM这样的工具……

编辑:也观察这个线程: 为什么线程共享堆空间?

您无法分析单个线程的堆使用情况。 如果您在执行外部代码时遇到问题,您应该尽可能地从其他线程中分离它并分析线程或堆转储。 这可以像VisualVM或JConsole一样提到,它也是由Oracle(或SUN)添加的。

根据子类可以执行的行为,我们可能会考虑选项。 例如,如果它是一个与数据库相关的操作,我们可以强制它们进行连接清理,如果它是基于文件的,我们可以强制它们通过你的类读取文件并检查文件有多大,如果它是任何http调用或者其他一些流function,我们可以相应地强制执行约束。

如果您只是担心堆大小利用率和内存泄漏,您可能需要查看http://java.dzone.com/tips/getting-jvm-heap-size-used ,它解释了如何获取运行时内存编程。 但是你必须定期进行检查,你永远无法确定内存使用是否是由子类行为引起的。

当我试图建立一个记录内存分配的代理时,我才发现这个 :

在post中如何跟踪Java中的任何对象创建,因为freeMemory()只报告长期存在的对象? 指定有一个开源项目Java Allocation Instrumenter ,您可以使用它来注册您自己的回调(它也有示例)并使用它来获得您所需的内容。

我几天前开始研究类似的项目,在研究时我发现了你的问题和下面的post。

我个人在一些unit testing中需要这种代码来检查是否在关键方法中分配了太多对象,并发现使用Runtime类是不合适的,因为Garbage collector可能会干扰并且测试记录了已分配内存的负数。