![](/img/trans.png)
[英]App engine Java: Sum difference two arrays - How to improve performance?
[英]How to improve my Java APP for better performance?
我对这类工作站的性能有一些疑问(现在将Spring Boot用于我的项目)。 如您很快就会了解的那样,我在一次学习大量信息时有些困惑。 因此,我将分享我不同类型的问题和一些测试,以了解流程并帮助像我这样困惑的其他人:
1)读取application.properties像这样:
@Value("${foo.name}")
private String name;
与从poo开始向类读取属性并通过getter获得其价值。
@ConfigurationProperties(prefix = "foo")
public class FooBean {
private String name;
private String age;
...
// setters and getters
}
1a)那么哪种方法更快,为什么呢? 如果存在差异,可以用内存性能来解释吗?1b)也可以说我使用FooBean方法,在Example1类中,我只需要FooBean的名称。 我应该在只需要1个字段的同时将FooBean注入到Example1类中还是应该使用@Value样式并仅获取特定的字段,该字段现在具有更好的性能?
2)我应该将FooBean的字段声明为静态的吗? 让我们来看一个例子:
配置类:
@Component
@ConfigurationProperties(prefix = "openstack")
@Data
@Validated
public class OpenStackBean {
@NotNull
@Valid
private String container;
@NotNull
@Valid
private String keystoneEndpoint;
@NotNull
@Valid
private String password;
@NotNull
@Valid
private String swiftEndpoint;
@NotNull
@Valid
private String tenantName;
@NotNull
@Valid
private String userName;
}
并且可以说此类仅由其Service使用:
@Service
public class OpenStackService implements IOpenStackService {
private OpenStackBean openStackBean;
@Autowired
public OpenStackService(OpenStackBean openStackBean) {
this.openStackBean = openStackBean;
}
...
...
private OSClientV2 authenticate(Facing perspective) throws AuthenticationException {
return OSFactory
.builderV2()
.endpoint(openStackBean.getKeystoneEndpoint())
.credentials(openStackBean.getUserName(), blowfish.decryptString(openStackBean.getPassword()))
.tenantName(openStackBean.getTenantName())
.perspective(perspective)
.withConfig(Config
.newConfig()
.withConnectionTimeout(applicationBean.getConnectionTimeout())
.withReadTimeout(applicationBean.getReadTimeout())
.withMaxConnections(10)
.withMaxConnectionsPerRoute(2))
.authenticate();
}
如果我是正确的,情况将是这样的:
1)在这种情况下,我将注入那些配置作为实例。 2)因此,每个类(假设我在一分钟内有10.000个用户,并且该类将被创建10.000次)将在堆栈中创建自己的配置,将其创建,并在完成后将其删除,因此可以再次释放内存。 3)但是因为会有很多请求,这是否会导致内存问题?
如果此流程正确,那我应该将OpenStackBean的字段创建为静态字段并将其作为private static OpenStackBean
注入吗? 它将被保存在堆中一次,所有用户将从那里获取它。 哪个性能更好?
3)这是我的一些测试结果,这使我开始考虑字符串操作和注入的性能。 这是使用JMeter进行压力测试的示例,并使用Java VisualVM进行可视化
发送10.000个请求
但是我不明白为什么堆使用总是增加。 这是APP的工作方式:
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity all(@ApiIgnore GameParam param) {
try {
// get games by categories by default
if (param.getPageNo() == null) {
return new ResponseEntity<>(gameService.getGamesByCategories(), HttpStatus.OK);
}
所有请求都进入此条件,并调用:
2)调用此函数。 由于categorizedGameList是静态的(在APP启动时初始化,并且将由Scheduler每天从远程服务器进行更新),因此所有请求都将直接返回2个步骤。 GameList位于堆中,因此不会创建新实例。
GameList-> 14 KB(14173字节)
@Override
public List<CategoryVO> getGamesByCategories() {
if (categorizedGameList != null) {
return categorizedGameList;
} else {
return getAndCategorizeGames();
}
}
3)那么为什么在10000个请求后,堆会增加300MB(从100增加到400)? 这意味着将为每个请求在内存中创建30 KB。
3a)当请求到达端点时会发生什么? 是否将创建APP的所有实例变量,或者仅创建访问的类? 我当时是这样想的:
我知道这太长了,无法阅读,但我尝试在此过程中提供所有经验。 我对提高性能有些困惑,因为我意识到自己从未考虑过。 谢谢你的耐心。
- 在这种情况下,我将注入这些配置作为实例。 2)因此,每个类(假设我在一分钟内有10.000个用户,并且该类将被创建10.000次)将在堆栈中创建自己的配置,将其创建,并在完成后将其删除,因此可以再次释放内存。 3)但是因为会有很多请求,这是否会导致内存问题?
不,这不是问题。 默认情况下,Spring Bean是“ Singleton”作用域(除非您显式设置了另一个作用域),因此将仅创建一个OpenStackBean实例。 因此,无需创建静态字段。
那么,为什么在10000个请求后堆增加300MB(从100到400)? 这意味着将为每个请求在内存中创建30 KB。
因为tomcat需要创建许多临时对象来处理请求,但是在处理完请求后它们将消失(还请注意,由于Java仅在垃圾回收之后才删除未使用的对象,因此堆使用率不会降低)
调用控制器的服务。 因此,该服务也是为此用户创建的。
这也是错误的,如果您的控制器是Singletone作用域,则仅创建一次。
当请求到达端点时,究竟发生了什么? 是否将创建APP的所有实例变量,或者仅创建访问的类?
不骂人的! 当tomcat服务您的请求时,仅需要实例化cals。
总的来说,您对性能问题的关注已经结束。 您应该关注的事情是何时未从内存中删除对象(GC使用直到应用程序崩溃后,内存使用量增加且没有减少)。 同样涉及内存占用是真实的,但与通过次要GC创建和销毁的一些小对象无关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.