【发布时间】:2016-11-15 11:52:20
【问题描述】:
我有一个 AWS Lambda 函数,仅配置了 128MB 内存,由 SNS 触发(它本身由 S3 触发)并将从 S3 下载文件。
在我的函数中,我有以下内容:
public class LambdaHandler {
private final AmazonS3Client s3Client = new AmazonS3Client();
public void gdeltHandler(SNSEvent event, Context context) {
System.out.println("Starting");
System.out.println("Found " + eventFiles.size() + " event files");
}
我已经注释掉并从这篇文章中排除了所有逻辑,因为我得到了一个 OutOfMemoryError,我已经将它隔离到了 AmazonS3Client 对象的创建中。当我取出那个物体时,我没有得到错误。上面的代码会导致 OutOfMemoryError。
我为函数分配了 128MB 的内存,这真的不足以简单地获取凭证并实例化 AmazonS3Client 对象吗?
我试过给 AmazonS3Client 构造函数
new EnvironmentVariableCredentialsProvider()
还有
new InstanceProfileCredentialsProvider()
结果相似。
创建 AmazonS3Client 对象是否只需要更多内存?
下面是堆栈跟踪:
元空间:java.lang.OutOfMemoryError java.lang.OutOfMemoryError: 元空间 com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder.build(BeanDeserializerBuilder.java:347) 在 com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:242) 在 com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143) 在 com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:409) 在 com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:358) 在 com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:265) 在 com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:245) 在 com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143) 在 com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:439) 在 com.fasterxml.jackson.databind.ObjectReader._prefetchRootDeserializer(ObjectReader.java:1588) 在 com.fasterxml.jackson.databind.ObjectReader.(ObjectReader.java:185) 在 com.fasterxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.java:558) 在 com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3108)
当我尝试提供 InstanceProfileCredentialsProvider 或 EnvironmentVariableCredentialsProvider 时,我得到以下堆栈跟踪:
线程“主”java.lang.Error 中的异常: java.lang.OutOfMemoryError:元空间在 lambdainternal.AWSLambda.(AWSLambda.java:62) 在 java.lang.Class.forName0(本机方法)在 java.lang.Class.forName(Class.java:348) 在 lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:94) 原因: java.lang.OutOfMemoryError:元空间在 java.lang.ClassLoader.defineClass1(本机方法)在 java.lang.ClassLoader.defineClass(ClassLoader.java:763) 在 java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 在 java.net.URLClassLoader.defineClass(URLClassLoader.java:467) 在 java.net.URLClassLoader.access$100(URLClassLoader.java:73) 在 java.net.URLClassLoader$1.run(URLClassLoader.java:368) 在 java.net.URLClassLoader$1.run(URLClassLoader.java:362) 在 java.security.AccessController.doPrivileged(Native Method) 在 java.net.URLClassLoader.findClass(URLClassLoader.java:361) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:424) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:357) 在 lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.makeRequestHandler(EventHandlerLoader.java:421) 在 lambdainternal.EventHandlerLoader.getTwoLengthHandler(EventHandlerLoader.java:777) 在 lambdainternal.EventHandlerLoader.getHandlerFromOverload(EventHandlerLoader.java:802) 在 lambdainternal.EventHandlerLoader.loadEventPojoHandler(EventHandlerLoader.java:888) 在 lambdainternal.EventHandlerLoader.loadEventHandler(EventHandlerLoader.java:740) 在 lambdainternal.AWSLambda.findUserMethodsImmediate(AWSLambda.java:126) 在 lambdainternal.AWSLambda.findUserMethods(AWSLambda.java:71) 在 lambdainternal.AWSLambda.startRuntime(AWSLambda.java:219) 在 lambdainternal.AWSLambda.(AWSLambda.java:60) ... 还有 3 个开始 RequestId:58837136-483e-11e6-9ed3-39246839616a 版本:$LATEST END 请求 ID:58837136-483e-11e6-9ed3-39246839616a 报告请求 ID: 58837136-483e-11e6-9ed3-39246839616a 持续时间:15002.92 毫秒 持续时间:15000 毫秒内存大小:128 MB 使用的最大内存:50 MB
2016-07-12T14:40:28.048Z 58837136-483e-11e6-9ed3-39246839616a 任务 15.00 秒后超时
编辑 1 如果我将分配给函数的内存增加到 192MB,它就可以正常工作,尽管很奇怪,在 cloudwatch 日志中报告只使用了 59MB 的内存。我只是失去了其余的记忆吗?
【问题讨论】:
-
您找到解决方案了吗?我认为元内存部分由于杰克逊导致的类加载而过载。元空间是总内存的百分比,因此如果增加总 jvm 内存,元空间将在抛出 OutOfMemoryError 之前获得更多内存。如果可以只增加内存的元空间部分,那就太好了。 (-XX:MaxMetaspaceSize=512m) 如果可能的话,另一个解决方案可能是调整杰克逊?元空间说明:plumbr.eu/outofmemoryerror/metaspace
-
没有我知道的解决方案...
-
FWIW,看起来可以将
JAVA_TOOL_OPTIONS环境变量传递给 Java 8 lambda
标签: amazon-web-services amazon-s3 aws-lambda