Ho una funzione AWS Lambda, configurata con solo 128 MB di memoria, viene attivata da SNS (che è a sua volta attivata da S3) e scaricherà il file da S3.OutOfMemoryError durante la creazione di AmazonS3Client in Lambda
Nella mia funzione, ho il seguente:
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");
}
Ho commentato fuori ed esclusa da questo post tutta la logica, perché sto ottenendo un OutOfMemoryError che ho isolato alla creazione del AmazonS3Client oggetto. Quando tengo fuori quell'oggetto, non ottengo l'errore. Il codice sopra riportato esita in OutOfMemoryError.
Ho assegnato 128 MB di memoria alla funzione, non è davvero sufficiente prendere semplicemente le credenziali e creare un'istanza dell'oggetto AmazonS3Client?
Ho provato dando il costruttore AmazonS3Client
new EnvironmentVariableCredentialsProvider()
così come
new InstanceProfileCredentialsProvider()
con risultati simili.
La creazione dell'oggetto AmazonS3Client richiede semplicemente più memoria?
Di seguito si riporta l'analisi dello stack:
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)
Quando provo fornire l'InstanceProfileCredentialsProvider o EnvironmentVariableCredentialsProvider, ottengo il seguente stack trace:
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
EDIT 1 Se io aumentare la memoria allocata alla funzione fino a 192MB, funziona bene, anche se abbastanza stranamente, riporta solo 59MB di memoria nei log di cloudwatch. Sto semplicemente perdendo il resto della memoria?
Hai trovato una soluzione per questo? Penso che la parte meta memoria sia sovraccarica a causa del caricamento di classe causato da Jackson. Il metaspace è una percentuale della memoria totale, quindi se si aumenta la memoria jm totale, il metaspace avrà più memoria con cui lavorare prima di generare un errore OutOfMemoryError. Sarebbe bello se fosse possibile aumentare semplicemente la parte metaspace della memoria. (-XX: MaxMetaspaceSize = 512m) Un'altra soluzione potrebbe essere quella di modificare Jackson se è possibile? Spiegazione di metaspace: https: // plumbr.eu/outofmemoryerror/metaspace –
Nessuna soluzione di cui sono a conoscenza ... – Brooks