typeorm-seeding icon indicating copy to clipboard operation
typeorm-seeding copied to clipboard

JavaScript heap out of memory

Open fegvilela opened this issue 4 years ago • 3 comments

Hello there!

I'm developing an API using Node, Express and TypeORM. I'm using docker and postgres (a container for API and another one for db, in dev environment).

My seeder was working before using factories, but as we got a lot of n - n relationships on entities, factories would be the sound way to seed.

I've been trying to use factories in the seeders, but when trying to execute it, JS run into a Fatal Error: heap out of memory.

Does anyone know how to solve this???

The error:

🌱  TypeORM Seeding v1.6.1
✔ ORM Config loaded
✔ Factories are imported
✔ Seeders are imported
✔ Database connected
â ‹ Executing CreateUsers Seeder
<--- Last few GCs --->

[218:0x64c14b0]    24326 ms: Mark-sweep (reduce) 2026.1 (2083.2) -> 2025.5 (2083.7) MB, 991.1 / 0.0 ms  (average mu = 0.097, current mu = 0.003) allocation failure scavenge might not succeed
[218:0x64c14b0]    25321 ms: Mark-sweep (reduce) 2026.6 (2083.7) -> 2026.0 (2084.2) MB, 991.6 / 0.0 ms  (average mu = 0.052, current mu = 0.003) allocation failure scavenge might not succeed


<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0xa7ac10 node::Abort() [/usr/local/bin/node]
 2: 0x9a3c4d node::FatalError(char const*, char const*) [/usr/local/bin/node]
 3: 0xc63f6e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 4: 0xc642e7 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 5: 0xe2dd65  [/usr/local/bin/node]
 6: 0xe2e90c  [/usr/local/bin/node]
 7: 0xe3c29b v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
 8: 0xe3ff9c v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
 9: 0xe03eba v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/usr/local/bin/node]
10: 0x115ac9b v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
11: 0x14f1df9  [/usr/local/bin/node]
Aborted (core dumped)
error Command failed with exit code 134.

user factory

import { define, factory } from 'typeorm-seeding';
import * as Faker from 'faker';
import User from '../../models/User';
import { LabelingTicket } from '../../models/LabelingTicket';

define(User, (faker: typeof Faker) => {
  faker.locale = 'pt_BR';

  const quantity = faker.random.number({ min: 2, max: 10 });

  const isSuperuser = faker.random.boolean();
  const username = faker.random.word();
  const password = faker.internet.password();

  const user = new User();
  user.username = username;
  user.isSuperuser = isSuperuser;
  user.password = password;
  user.hashPassword();

  user.labelingTickets = Array(
    factory(LabelingTicket)().createMany(quantity) as any,
  );
  return user;
});

create user seed

import { Seeder, Factory } from 'typeorm-seeding';
import { Connection } from 'typeorm';

import User from '../../models/User';

export default class CreateUsers implements Seeder {
  public async run(factory: Factory, connection: Connection): Promise<any> {
    await factory(User)().create();
  }
}

dockerfile

FROM node:15
WORKDIR /usr/src/app
COPY package.json ./
COPY yarn.lock ./
COPY . .
RUN yarn
RUN yarn add ts-node
EXPOSE 3333

container stats at normal operation

CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O        PIDS
115b721ee6f0   api-dev   1.28%     460.8MiB / 15.25GiB   2.95%     165kB / 40.6kB   343MB / 3.76GB   25

container stats when running seeds

CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O        PIDS
115b721ee6f0   api-dev   388.59%    1.992GiB / 15.25GiB   13.06%     165kB / 40.6kB   343MB / 3.76GB   48

Thanks!

fegvilela avatar Feb 24 '21 12:02 fegvilela

what if you run ts-node with --max-old-space-size flag?
node -r ts-node/register --max-old-space-size=4096

this could be a memory leak tho.

micalevisk avatar Mar 08 '21 02:03 micalevisk

I'm looking on resolveEntity method, for me its quite unclear and could be better, probably related on the behaviour of:

  user.labelingTickets = Array(
    factory(LabelingTicket)().createMany(quantity) as any,
  );

Let me take a look on this.

jorgebodega avatar Oct 08 '21 13:10 jorgebodega

Hi! I've been testing this and I cannot reproduce the problem.

I you checkout 117-javascript-heap-out-of-memory, I've modified the sample to approach your problem, please try if you can or add some comment with changes.

Or maybe you can create a repository that reproduces your problem. That will help us a lot, not so much time to discover errors.

Thanks!

jorgebodega avatar Oct 11 '21 18:10 jorgebodega