我们已经构建了一个内存数据库,它在一个Vec中占用大约100-150G RAM ,其填充方式如下:
let mut result = Vec::with_capacity(a_very_large_number);
while let Ok(n) = reader.read(&mut buffer) {
result.push(...);
}
Run Code Online (Sandbox Code Playgroud)
perf top 表明时间主要花在这个"change_protection"函数上:
Samples: 48K of event 'cpu-clock', Event count (approx.): 694742858
62.45% [kernel] [k] change_protection
18.18% iron [.] database::Database::init::h63748
7.45% [kernel] [k] vm_normal_page
4.88% libc-2.17.so [.] __memcpy_ssse3_back
0.92% [kernel] [k] copy_user_enhanced_fast_string
0.52% iron [.] memcpy@plt
Run Code Online (Sandbox Code Playgroud)
随着越来越多的数据加载到RAM中,此函数的CPU使用率也在增长:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
12383 iron 20 0 137g 91g 1372 D 76.1 37.9 27:37.00 iron …Run Code Online (Sandbox Code Playgroud) @Path(value = "/user")
@Stateless
public class UserService {
@Inject
private UserManager manager;
@Path(value = "/create")
@GET
@Produces(value = MediaType.TEXT_PLAIN)
public String doCreate(@QueryParam(value = "name") String name) {
manager.createUser(name);
return "OK";
}
}
Run Code Online (Sandbox Code Playgroud)
这是用户管理器impl
public class UserManager {
@PersistenceContext(unitName = "shop")
private EntityManager em;
public void createUser(String name) {
User user = new User();
user.setName(name);
// skip some more initializations
em.persist(user);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是如果我没有将UserService标记为@Stateless,那么manager字段为null
但如果我标记@Stateless,我可以注入管理器字段,并且应用程序工作,因为我可以将数据保存到数据库中
只是想知道,这背后的原因是什么?
这是连接应用程序的首选方式吗?
好吧,我正在考虑将EntityManager拉出到生产者,以便它可以共享