java while循环内存泄漏
我使用while循环从AmazonSQS获取消息。部分代码如下:java while循环内存泄漏,java,memory-leaks,while-loop,Java,Memory Leaks,While Loop,我使用while循环从AmazonSQS获取消息。部分代码如下: ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl); while (true) { List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages(); if (messages.size()
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl);
while (true) {
List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages();
if (messages.size() > 0) {
MemcachedClient c = new MemcachedClient(new BinaryConnectionFactory(), AddrUtil.getAddresses(memAddress));
for (Message message : messages) {
// get message from aws sqs
String messageid = message.getBody();
String messageRecieptHandle = message.getReceiptHandle();
sqs.deleteMessage(new DeleteMessageRequest(myQueueUrl, messageRecieptHandle));
// get details info from memcache
String result = null;
String key = null;
key = "message-"+messageid;
result = c.get(key);
}
c.shutdown();
}
}
ReceiveMessageRequest ReceiveMessageRequest=new ReceiveMessageRequest(myQueueUrl);
while(true){
List messages=sqs.receiveMessage(receiveMessageRequest.getMessages();
如果(messages.size()>0){
MemcachedClient c=newmemcachedclient(newbinaryconnectionfactory(),AddrUtil.getAddresses(memAddress));
用于(消息:消息){
//从aws sqs获取消息
字符串messageid=message.getBody();
字符串messageReceiptHandle=message.getReceiptHandle();
deleteMessage(新的DeleteMessageRequest(myQueueUrl,MessageReceiptHandle));
//从memcache获取详细信息
字符串结果=null;
字符串键=null;
key=“message-”+messageid;
结果=c.get(键);
}
c、 关机();
}
}
在这种情况下会导致内存泄漏吗?
我使用“ps aux”进行了检查。我发现RSS(常驻集大小,任务使用的非交换物理内存)增长缓慢。您无法仅根据进程的RSS评估Java应用程序是否存在内存泄漏。大多数JVM都非常贪婪,他们宁愿从操作系统中获取更多内存,也不愿在垃圾收集上花费大量精力 也就是说,您的while循环似乎也没有任何明显的内存“泄漏”,但这取决于某些方法调用的功能(上面没有包括)。如果您将内容存储在静态变量中,这可能会引起关注,但是如果唯一的引用在循环的范围内,您可能就没事了
要知道某个代码区域是否存在内存泄漏,最简单的方法是在应用程序的一次运行中严格执行该代码(可能设置为相对较低的最大堆大小)。如果出现OutOfMemoryError,则可能存在内存泄漏。您无法仅根据进程的RSS来评估Java应用程序是否存在内存泄漏。大多数JVM都非常贪婪,他们宁愿从操作系统中获取更多内存,也不愿在垃圾收集上花费大量精力 也就是说,您的while循环似乎也没有任何明显的内存“泄漏”,但这取决于某些方法调用的功能(上面没有包括)。如果您将内容存储在静态变量中,这可能会引起关注,但是如果唯一的引用在循环的范围内,您可能就没事了
要知道某个代码区域是否存在内存泄漏,最简单的方法是在应用程序的一次运行中严格执行该代码(可能设置为相对较低的最大堆大小)。如果出现OutOfMemoryError,可能是内存泄漏。很抱歉,但我在这里没有看到从消息队列中删除消息的代码。你清理邮件列表了吗?如果DeleteRequest从队列中删除了消息,则尝试修改您创建的消息列表
另外,您还可以使用visualvm工具(现在是JDK的一部分)获得更好的内存使用统计信息。对不起,这里没有看到从消息队列中删除消息的代码。你清理邮件列表了吗?如果DeleteRequest从队列中删除了消息,则尝试修改您创建的消息列表
此外,您还可以使用visualvm工具(现在是JDK的一部分)获得更好的内存使用统计信息。您正在定义循环中的变量。将定义移到循环上方,并在循环中重用/重新分配。这只会增加开销,它们使用的是同一个指针,不是吗?@D.N:这应该不会有太大的区别。编译器足够聪明,只需在堆栈上分配一次必要的局部变量。@D.N.:这只会恶化内存使用。如果您将变量保持在尽可能窄的范围内,那么当不再需要时,您总是有最大的机会使内存脱离范围。您是否遇到OOM异常?JVM在执行GC之前可以自由决定它使用了多少内存。将定义移到循环上方,并在循环中重用/重新分配。这只会增加开销,它们使用的是同一个指针,不是吗?@D.N:这应该不会有太大的区别。编译器足够聪明,只需在堆栈上分配一次必要的局部变量。@D.N.:这只会恶化内存使用。如果您将变量保持在尽可能窄的范围内,那么当不再需要时,您总是有最大的机会使内存脱离范围。您是否遇到OOM异常?JVM在执行GC之前可以自由决定使用多少内存。每次迭代都应该删除对对象的引用。因此,列表大小不应导致问题我不清理列表消息。我从列表中获得一条消息,然后从SQS中删除该消息。但我不接触列表消息。在下一次迭代中,List messages从SQS获取新消息的列表。这是一个问题吗?@chnet:我想知道你的SQS是否引起了问题。消息应该是指向从SQS接收的对象的另一个引用。应该是ok@chnet:您可以转储队列的大小,以便知道是否存在泄漏或不泄漏。对于每个迭代,应该删除对对象的引用。因此,列表大小不应导致问题我不清理列表消息。我从列表中获得一条消息,然后从SQS中删除该消息。但我不接触列表消息。在下一次迭代中,List messages从SQS获取新消息的列表。这是一个问题吗?@chnet:我想知道你的SQS是否引起了问题。消息应该是指向从SQS接收的对象的另一个引用。应该是ok@chnet:您可以转储队列的大小,以便知道是否存在泄漏