我正在创建一个 java 程序,我的班级假设 A 有一些预定义的行为。但是用户可以覆盖我的类来改变它的行为。所以我的脚本会检查是否有一些子类,而不是我称之为行为的,但是如果他在他的代码中编写了一些阻塞代码或内存泄漏怎么办。
这可能会损害我的过程。java中是否有任何方法可以监视某种方法分配的内存。
请建议。
我正在创建一个 java 程序,我的班级假设 A 有一些预定义的行为。但是用户可以覆盖我的类来改变它的行为。所以我的脚本会检查是否有一些子类,而不是我称之为行为的,但是如果他在他的代码中编写了一些阻塞代码或内存泄漏怎么办。
这可能会损害我的过程。java中是否有任何方法可以监视某种方法分配的内存。
请建议。
但是如果他在他的代码中写了一些阻塞代码或内存韭菜怎么办
首先,我建议你好好记录你的课程。描述允许用户做什么和不能做什么。给出用例做什么(如果可能的话)。
对于阻塞代码部分,如果您有一些时间问题,您可以将方法的执行包装在 a 中Future
并让 aExecutorService
执行代码。这样,如果执行时间过长,您将能够取消执行。
对于内存泄漏问题,我想您不是在谈论内存泄漏,而是由于调用覆盖的方法而导致的内存消耗增加。毕竟,Java 中的内存泄漏很少见。
您将无法检测方法的内存消耗,这不是 java 的工作方式。内存是全局的。例如,如果加载了一个外部库(JNI),或者类路径中的某个库被调用,现在将使用更多内存,你会怎么做?你就是说不出来。
除了监控整体内存消耗之外,没有其他方法(如果我错了,请告诉我)。
对于外部监控,您可以使用 VisualVM 或 JConsole(JDK 的一部分),对于内部您可以使用 Runtime 类:
Runtime rt = Runtime.getRuntime();
long totalMem = rt.totalMemory();
long maxMem = rt.maxMemory();
long freeMem = rt.freeMemory();
通过 Thread 类,您可以检查所有线程的状态。从未直接使用它,因为应用程序服务器或批处理 API 正在完成它们的工作......所以,我不需要重新发明轮子。我建议使用VisualVM之类的工具...
编辑:还看这个线程:为什么线程共享堆空间?
您无法分析单个线程的堆使用情况。如果您在执行外部代码时遇到问题,您应该尽可能将其与其他线程分离并分析线程或堆转储。这可以通过 Oracle(或 SUN)添加的 VisualVM 或 JConsole 来完成。
根据子类可以做什么样的行为,那么我们可能会想到选项。例如,如果是数据库相关操作,我们可以强制他们进行连接清理,如果是基于文件的,我们可以强制他们通过您的类读取文件并检查文件有多大,如果是任何 http 调用或其他一些流功能,我们可以相应地查看强制约束。
如果您只是担心堆大小利用率和内存泄漏,您可能需要查看http://java.dzone.com/tips/getting-jvm-heap-size-used,它解释了如何获取运行时内存以编程方式。但是你必须定期检查,你永远无法确定内存使用是否是由子类行为引起的。
我只是在尝试建立一个记录内存分配的代理时发现了这一点:
在帖子中如何跟踪 Java 中的任何对象创建,因为 freeMemory() 只报告长期存在的对象?它指定有一个开源项目Java Allocation Instrumenter,您可以使用它来注册您自己的回调(它也有示例)并使用它可以获得您需要的东西。
几天前我开始从事一个类似的项目,在研究时我发现了你的问题和下面的帖子。
我个人在一些单元测试中需要这种代码来检查是否在关键方法中分配了太多对象,并发现使用Runtime
类是不合适的,因为Garbage collector
可能会干扰并且测试记录了分配内存的负数。
Oracle 有一个很好的关于解决内存泄漏的文档。它建议人们应该使用 NetBeans Profiler 作为一种工具。
http://www.oracle.com/technetwork/java/javase/memleaks-137499.html
我相信您可以在运行时使用相同的调试 API 来检查行为不端的代码,但这会带来性能损失,并且可能类似于用大锤杀死苍蝇。我个人不会让这样的东西在生产中运行。相反,我会依靠严格的测试和同行评审。