Spring AOP 在内存消耗情况下的效率如何
How efficient is Spring AOP in case of memory consumption
在我的宠物项目中,我有一个很长的 运行 工作,我想向用户显示有关该过程的状态以及它进行了多长时间。因此,我将状态对象推送到 JMS 主题,从那里获取并馈送到 WS 应用程序以将它们流式传输到有效的客户端。
我在spring AOP(即@Before,@AfterReturn)中写了切点并调用我的服务将消息发送到主题。现在我想记录服务的状态,而不是在方法开始时或方法内部 return 之后。所以我调用了服务(注入了 jmsTamplete 并获取了状态对象)。有什么办法可以最大限度地减少这些呼叫,以便我无法重复服务呼叫。
这是我的 sudo 代码。
public class Myservice{
UserDao userDao;
LegService legservice;
ProviderDao providerDao;
....
StatusServive statusServie;
//aop will call the same service to send info to JMS topic
fetchandCalculateLeg(){
// here i called statusServie.senStatus(StatusObject);
List<Users> = userDao.fetchUserInfo();
// here i called statusServie.senStatus(StatusObject);
....
loop: #forEachUser
// here i called statusServie.senStatus(StatusObject);
someList = legservice.fecthLegInfoForEachUser();
// here i called statusServie.senStatus(StatusObject);
:endloop;
....
} }
目前我有 3 个长 运行 任务,我在每个方法中都调用相同的方法 class。我想尽量减少通话。
编辑1:
我也可以在调用方法上应用 AOP,但在这种情况下性能如何?如何衡量 AOP 性能(在应用程序启动或创建代理对象期间消耗了多少内存)。抱歉问了这么多问题。
如果您使用 AOP,性能会比这更好,因为它经过充分测试和优化的框架来执行此类操作。无论如何,您可以通过减去开始和结束时间来检查。
您可以使用当前代码和 AOP 实现代码来检查性能。这将是一项非常有趣的工作。执行如下操作以设置开始和结束时间并减去。
System.currentTimeMillis()
以上语法,Returns当前时间(以毫秒为单位)。请注意,虽然 return 值的时间单位是毫秒,但该值的粒度取决于底层操作系统,可能更大。例如,许多操作系统以几十毫秒为单位测量时间。
有关 "computer time" 和协调世界时 (UTC) 之间可能出现的细微差异的讨论,请参阅 class 日期的描述。
有许多可用的 AOP 开源框架。
Spring AOP:使用 Spring 框架的 AOP。广告。 Spring 框架的关键组件之一是面向方面的编程 (AOP) 框架。面向方面的编程需要将程序逻辑分解成不同的部分,称为所谓的关注点。
AspectJ: AspectJ 是 Java 编程语言的面向方面的无缝扩展,Java 平台兼容且易于使用学习和使用。 AspectJ 支持横切关注点的干净模块化,例如:错误检查和处理、同步、上下文相关行为、性能优化、监视和日志记录、调试支持、多对象协议。
AspectWerkz: AspectWerkz 是 Java 的动态、轻量级和高性能 AOP 框架。 AspectWerkz 既强大又简单,将帮助您轻松地将 AOP 集成到新项目和现有项目中。 AspectWerkz 利用运行时字节码修改在运行时编织您的 classes。它挂钩并编织由任何 class 加载器加载的 classes,除了 bootstrap class 加载器。它具有丰富且高度正交的连接点模型。方面、建议和介绍以普通 Java 编写,您的目标 classes 可以是常规的 POJO。您可以添加、删除和重组通知,以及在运行时交换您的介绍的实现。您的方面可以使用 XML 定义文件或使用运行时属性来定义。
编辑 1
Spring也支持AspectJ。我确实使用 AspectJ 1.7.2 对其进行了测试,它没有显示内存泄漏。您可以通过创建大量 bean 然后在一段时间后进行堆转储来在您的应用程序中复制相同内容,因为垃圾收集需要一些时间,它不是即时的。
作为,根据我的测试。性能不错,没有大量调用。
简单示例在 MKYong 中可用:http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/
注意:你应该修改你的问题表现是测量时间和space。而且,根据您的评论,您似乎在询问更多关于内存优化或管理的内容。还有,你的问题主题和question不一样。
你问的不是很清楚,题目有误导性。
你真的可以使用 Spring Aop 来完成你想做的任务,你只需要注入日志调用方法 fetchUserInfo() 和 fecthLegInfoForEachUser() 等等。
你也可以使用@Around来更好的控制。
对于性能方面,鉴于这段代码非常有限,您可以使用和不使用 aop 轻松地进行一些分析。
请记住,用于日志记录的 AOP 使用非常广泛,并且 Spring 为许多实体和目的创建代理对象,例如工厂,因此经过良好测试和性能。
(1)较长的 运行 任务意味着 'jobs',因此您可能需要:Quartz
(2)如果你只是想知道你的程序去了哪里,你可能需要一个日志记录工具:Logback。一个定义良好的附加程序将解决你的问题。
如果您有这么持久的工作,为什么不将其放入 Spring-Batch 运行时?实施自定义 reader -> 处理器 -> 编写器,系统将为您完成所有工作。为了显示此类作业执行的详细信息,我创建了此类 DTO https://gist.github.com/idyoshin/b035317db8c61b1b49ccb8898848171e and collector https://gist.github.com/idyoshin/74ad80841a51e1be62208f3fd58eeb6a。这个实用程序是解决方法,因为我不想将 spring-batch 管理应用程序嵌入到我的主应用程序中。我使用它们来显示 active/archive 执行我的系统的特定作业(基于名称)的详细信息。
您还可以使用此类实用程序实现自定义的基于计时器的数据收集器,该收集器会将此数据推送到 JMS 或 Websocket。 Spring-batch 也有很好的监听器,你可以实现它,例如自定义 org.springframework.batch.core.ChunkListener
将允许你进行 "progress-bar" 之类的更新 - 你会知道你的块被处理的时刻,并且因此出现了进展更新。
与您最初的 AOP 解决方案相比,使用 Spring 批处理的方法将是直截了当的(纯 java 代码),并且还会解决您的其他问题:持久事务大更新:它将整个数据集切成块,并在单个事务中处理每个块。
在我的宠物项目中,我有一个很长的 运行 工作,我想向用户显示有关该过程的状态以及它进行了多长时间。因此,我将状态对象推送到 JMS 主题,从那里获取并馈送到 WS 应用程序以将它们流式传输到有效的客户端。 我在spring AOP(即@Before,@AfterReturn)中写了切点并调用我的服务将消息发送到主题。现在我想记录服务的状态,而不是在方法开始时或方法内部 return 之后。所以我调用了服务(注入了 jmsTamplete 并获取了状态对象)。有什么办法可以最大限度地减少这些呼叫,以便我无法重复服务呼叫。 这是我的 sudo 代码。
public class Myservice{
UserDao userDao;
LegService legservice;
ProviderDao providerDao;
....
StatusServive statusServie;
//aop will call the same service to send info to JMS topic
fetchandCalculateLeg(){
// here i called statusServie.senStatus(StatusObject);
List<Users> = userDao.fetchUserInfo();
// here i called statusServie.senStatus(StatusObject);
....
loop: #forEachUser
// here i called statusServie.senStatus(StatusObject);
someList = legservice.fecthLegInfoForEachUser();
// here i called statusServie.senStatus(StatusObject);
:endloop;
....
} }
目前我有 3 个长 运行 任务,我在每个方法中都调用相同的方法 class。我想尽量减少通话。
编辑1: 我也可以在调用方法上应用 AOP,但在这种情况下性能如何?如何衡量 AOP 性能(在应用程序启动或创建代理对象期间消耗了多少内存)。抱歉问了这么多问题。
如果您使用 AOP,性能会比这更好,因为它经过充分测试和优化的框架来执行此类操作。无论如何,您可以通过减去开始和结束时间来检查。
您可以使用当前代码和 AOP 实现代码来检查性能。这将是一项非常有趣的工作。执行如下操作以设置开始和结束时间并减去。
System.currentTimeMillis()
以上语法,Returns当前时间(以毫秒为单位)。请注意,虽然 return 值的时间单位是毫秒,但该值的粒度取决于底层操作系统,可能更大。例如,许多操作系统以几十毫秒为单位测量时间。 有关 "computer time" 和协调世界时 (UTC) 之间可能出现的细微差异的讨论,请参阅 class 日期的描述。
有许多可用的 AOP 开源框架。
Spring AOP:使用 Spring 框架的 AOP。广告。 Spring 框架的关键组件之一是面向方面的编程 (AOP) 框架。面向方面的编程需要将程序逻辑分解成不同的部分,称为所谓的关注点。
AspectJ: AspectJ 是 Java 编程语言的面向方面的无缝扩展,Java 平台兼容且易于使用学习和使用。 AspectJ 支持横切关注点的干净模块化,例如:错误检查和处理、同步、上下文相关行为、性能优化、监视和日志记录、调试支持、多对象协议。
AspectWerkz: AspectWerkz 是 Java 的动态、轻量级和高性能 AOP 框架。 AspectWerkz 既强大又简单,将帮助您轻松地将 AOP 集成到新项目和现有项目中。 AspectWerkz 利用运行时字节码修改在运行时编织您的 classes。它挂钩并编织由任何 class 加载器加载的 classes,除了 bootstrap class 加载器。它具有丰富且高度正交的连接点模型。方面、建议和介绍以普通 Java 编写,您的目标 classes 可以是常规的 POJO。您可以添加、删除和重组通知,以及在运行时交换您的介绍的实现。您的方面可以使用 XML 定义文件或使用运行时属性来定义。
编辑 1
Spring也支持AspectJ。我确实使用 AspectJ 1.7.2 对其进行了测试,它没有显示内存泄漏。您可以通过创建大量 bean 然后在一段时间后进行堆转储来在您的应用程序中复制相同内容,因为垃圾收集需要一些时间,它不是即时的。
作为,根据我的测试。性能不错,没有大量调用。
简单示例在 MKYong 中可用:http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/
注意:你应该修改你的问题表现是测量时间和space。而且,根据您的评论,您似乎在询问更多关于内存优化或管理的内容。还有,你的问题主题和question不一样。
你问的不是很清楚,题目有误导性。
你真的可以使用 Spring Aop 来完成你想做的任务,你只需要注入日志调用方法 fetchUserInfo() 和 fecthLegInfoForEachUser() 等等。 你也可以使用@Around来更好的控制。
对于性能方面,鉴于这段代码非常有限,您可以使用和不使用 aop 轻松地进行一些分析。 请记住,用于日志记录的 AOP 使用非常广泛,并且 Spring 为许多实体和目的创建代理对象,例如工厂,因此经过良好测试和性能。
(1)较长的 运行 任务意味着 'jobs',因此您可能需要:Quartz
(2)如果你只是想知道你的程序去了哪里,你可能需要一个日志记录工具:Logback。一个定义良好的附加程序将解决你的问题。
如果您有这么持久的工作,为什么不将其放入 Spring-Batch 运行时?实施自定义 reader -> 处理器 -> 编写器,系统将为您完成所有工作。为了显示此类作业执行的详细信息,我创建了此类 DTO https://gist.github.com/idyoshin/b035317db8c61b1b49ccb8898848171e and collector https://gist.github.com/idyoshin/74ad80841a51e1be62208f3fd58eeb6a。这个实用程序是解决方法,因为我不想将 spring-batch 管理应用程序嵌入到我的主应用程序中。我使用它们来显示 active/archive 执行我的系统的特定作业(基于名称)的详细信息。
您还可以使用此类实用程序实现自定义的基于计时器的数据收集器,该收集器会将此数据推送到 JMS 或 Websocket。 Spring-batch 也有很好的监听器,你可以实现它,例如自定义 org.springframework.batch.core.ChunkListener
将允许你进行 "progress-bar" 之类的更新 - 你会知道你的块被处理的时刻,并且因此出现了进展更新。
与您最初的 AOP 解决方案相比,使用 Spring 批处理的方法将是直截了当的(纯 java 代码),并且还会解决您的其他问题:持久事务大更新:它将整个数据集切成块,并在单个事务中处理每个块。