OutOfMemoryError issue when using custom front end code

shahab9 months ago

Hello,
i am using traccar(5.6) as a backend and based on the modern app i have build my own front end in react. I have around 1300 devices which are sending message around every 5 sec.
Initially i use traccar with modern app and it works fine but when i shifted to my custom frontend code then there is OutOfMemoryError problem which happens after connection of the websocket, there will be some message comes as usual and then traccar server crash due to OutOfMemoryError
I have copy pasted the exact code(adjustment of code refactoring) of modern app to handle websocket but still i was not able to understand what the he issue

here is the log

2023-08-18 12:54:43  WARN: Task produce failed - Java heap space - OutOfMemoryError
2023-08-18 12:54:44 ERROR: Thread exception - Java heap space - OutOfMemoryError
2023-08-18 12:54:43  WARN: An exception 'java.lang.OutOfMemoryError: Java heap space' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception: - Java heap space - OutOfMemoryError
2023-08-18 12:54:43  INFO: [T7455da47] error - Java heap space - OutOfMemoryError
2023-08-18 12:54:43  WARN: Unexpected exception from an event executor:  - Java heap space - OutOfMemoryError
2023-08-18 12:54:44 ERROR: Thread exception - Java heap space - OutOfMemoryError
2023-08-18 12:54:44 ERROR: Thread exception - Java heap space - OutOfMemoryError
2023-08-18 12:54:44  WARN: An exception 'java.lang.OutOfMemoryError: Java heap space' [enable DEBUG level for full stacktrace] was thrown by a user handler's exceptionCaught() method while handling the following exception: - Java heap space - OutOfMemoryError
2023-08-18 12:54:44  INFO: [T7455da47] disconnected
2023-08-18 12:54:44 ERROR: Thread exception - Java heap space - OutOfMemoryError

this is my socket(frontend) code

import { useRef } from 'react';
import { useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { trackActions } from '../store/track';
import { useEffectAsync, useRistrictions } from '../hooks';
import { errorsActions } from '../store/errors';

const logoutCode = 4000;

const TrackSocketProvider = () => {
  const dispatch = useDispatch();

  const location = useLocation();
  const { isTracker } = useRistrictions();

  const socketRef = useRef();

  const idsToTrack = useSelector((state) => state.track._trackIds);

  const connectSocket = () => {
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    const socket = new WebSocket(`${protocol}//${window.location.host}/api/socket`);

    socketRef.current = socket;

    socket.onopen = () => {};

    socket.onclose = async (event) => {
      if (event.code !== logoutCode) {
        try {
          const positionsResponse = await fetch('/api/positions');
          if (positionsResponse.ok) {
            dispatch(trackActions.update(await positionsResponse.json()));
          }
          if (positionsResponse.status === 401) {
            dispatch(errorsActions.push({ data: 'Un authorised', status: 401 }));
          }
        } catch (error) {}
        setTimeout(() => connectSocket(), 60000);
      }
    };

    socket.onmessage = (event) => {
      const eventData = JSON.parse(event.data) || {};
      if (Object.prototype.hasOwnProperty.call(eventData, 'positions')) {
        eventData.positions.forEach(({ attributes, deviceId, ...position }) => {
          if (idsToTrack.includes(deviceId)) {
            dispatch(trackActions.updatePositions({ deviceId, ...position }));
            dispatch(trackActions.updateAttributes({ deviceId, ...attributes }));
          }
        });
      }
    };
  };

  useEffectAsync(async () => {
    if (isTracker && location.pathname.startsWith('/track')) {
      const positionsResponse = await fetch('/api/positions');
      if (positionsResponse.ok) connectSocket();
      return () => {
        const socket = socketRef.current;
        if (socket) socket.close(logoutCode);
      };
    }
    return null;
  }, [location, isTracker]);

  return null;
};

export default TrackSocketProvider;
Anton Tananaev9 months ago
  • What made you think it's related to WebSocket connection?
  • How many WebSocket connections do you have at the same time?
  • How much memory do you have allocated to Traccar?
shahab9 months ago
  1. while developing the custom frontend code, i have integrate live tracking(websocket) at the total end. Without live tracking(websocket) all things are working fine, only after implementing it traccar server is crashing
  2. i am testing with only 2 web socket connection
  3. i have alloted 16gb of ram out of 32 gb in my ec2 and mysql db is also on the same virtual machine
    here is server usage :- https://ibb.co/cgrjvNJ
Anton Tananaev9 months ago

On your screenshot I see it's using only 3% of memory, which does not match with what you're saying. Can you please provide some evidence that you allocated 16GB to Traccar.

shahab9 months ago

I have used this command from optmization documentation

ExecStart=/opt/traccar/jre/bin/java -Xmx16G -jar tracker-server.jar conf/traccar.xml
Anton Tananaev9 months ago

As you can probably notice yourself, something doesn't add up here. So that should be a good lead for you to troubleshoot.

shahab9 months ago

i dont think it is an issue with traccar server as it is working absolutely fine with modern app, it is causing error only with custom frontend. out of my 2 websocket connection, 1 is from modern app and second one is from my custom frontend

as per me, there is something which i am missing in the whole socket connection, let me just tell what i have understood from modern app

  1. after login a session will create and based on that session api/socket will call and socket connection got established
  2. if you refresh then get session api will call and socket connection resume
  3. on logout socket connection will close