gpt4 book ai didi

amazon-web-services - 在 Lambda 中创建 AmazonS3Client 时出现 OutOfMemoryError

转载 作者:行者123 更新时间:2023-12-03 10:28:26 24 4
gpt4 key购买 nike

我有一个 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 对象的创建是否只需要更多内存?

下面是堆栈跟踪:

Metaspace: java.lang.OutOfMemoryError java.lang.OutOfMemoryError: Metaspace at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder.build(BeanDeserializerBuilder.java:347) at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:242) at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:409) at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:358) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:265) at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:245) at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143) at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:439) at com.fasterxml.jackson.databind.ObjectReader._prefetchRootDeserializer(ObjectReader.java:1588) at com.fasterxml.jackson.databind.ObjectReader.(ObjectReader.java:185) at com.fasterxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.java:558) at com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3108)



当我尝试提供 InstanceProfileCredentialsProvider 或 EnvironmentVariableCredentialsProvider 时,我得到以下堆栈跟踪:

Exception in thread "main" java.lang.Error: java.lang.OutOfMemoryError: Metaspace at lambdainternal.AWSLambda.(AWSLambda.java:62) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:94) Caused by: java.lang.OutOfMemoryError: Metaspace at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.makeRequestHandler(EventHandlerLoader.java:421) at lambdainternal.EventHandlerLoader.getTwoLengthHandler(EventHandlerLoader.java:777) at lambdainternal.EventHandlerLoader.getHandlerFromOverload(EventHandlerLoader.java:802) at lambdainternal.EventHandlerLoader.loadEventPojoHandler(EventHandlerLoader.java:888) at lambdainternal.EventHandlerLoader.loadEventHandler(EventHandlerLoader.java:740) at lambdainternal.AWSLambda.findUserMethodsImmediate(AWSLambda.java:126) at lambdainternal.AWSLambda.findUserMethods(AWSLambda.java:71) at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:219) at lambdainternal.AWSLambda.(AWSLambda.java:60) ... 3 more START RequestId: 58837136-483e-11e6-9ed3-39246839616a Version: $LATEST END RequestId: 58837136-483e-11e6-9ed3-39246839616a REPORT RequestId: 58837136-483e-11e6-9ed3-39246839616a Duration: 15002.92 ms Billed Duration: 15000 ms Memory Size: 128 MB Max Memory Used: 50 MB
2016-07-12T14:40:28.048Z 58837136-483e-11e6-9ed3-39246839616a Task timed out after 15.00 seconds



编辑 1 如果我将分配给该函数的内存增加到 192MB,它就可以正常工作,尽管很奇怪,在 cloudwatch 日志中报告只使用了 59MB 的内存。我只是失去了其余的内存吗?

最佳答案

减少冷启动的一种方法是将内存设置为 1536 mb 并将超时设置为 15 分钟。这将使专用主机仅运行您的 lambda,而不是在共享主机上运行您的 lambda + 当必须启动新实例时,它将从主机上的缓存中复制代码,而不是从 S3 中复制。
不过这会更贵,如果您不想这样做,请继续阅读下文。
如何减少冷启动时间?

  • 遵循 Lambda 最佳实践
    https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html
  • 通过为您的函数选择更大的内存设置
    将内存视为“电源”设置,因为它还决定了您的函数将接收多少 CPU。
  • 通过减小函数 ZIP 的大小
    这可能意味着减少包含在函数 ZIP 中的依赖项数量。
    使用 ProGuard 可以进一步减小 Java JAR 的大小
  • [仅限 Java] 使用 bytestream 接口(interface)而不是 POJO 接口(interface)。
    Lambda 在内部使用的 JSON 序列化库可能需要一些时间才能启动。这将需要您完成开发工作,但您可以通过使用字节流接口(interface)和轻量级 JSON 库来改进这一点。以下是一些可能有帮助的链接:
    http://docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-stream.html
    https://github.com/FasterXML/jackson-jr
  • [仅限 Java] 不要使用替代匿名类(lambda、方法引用、构造函数引用等)的 Java 8 特性
    我们在内部注意到,与 Java 8 Lambda 相关的字节码似乎会导致启动性能欠佳。如果您的代码正在使用任何 Java 8 功能来替换匿名类(lambda、方法引用、构造函数引用等),那么您可以通过返回到匿名类来获得更好的启动时间。
  • 通过使用不同的运行时
    不同的运行时有不同的冷启动时间,以及不同的运行时性能。虽然 NodeJS 可能更适合繁重的 IO 工作,但 Go 可能更适合执行大量并发工作的代码。客户已经做了一些基本的基准测试来比较 Lambda 上的语言性能,这里是对不同编程语言性能的更通用的比较。没有万能的答案,请使用对您的要求有意义的方法。

  • 基本基准: https://read.acloud.guru/comparing-aws-lambda-performance-of-node-js-python-java-c-and-go-29c1163c2581
    通用比较: https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fast.html

    关于amazon-web-services - 在 Lambda 中创建 AmazonS3Client 时出现 OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38342418/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com