Ошибка вывода памяти: пространство кучи Java при извлечении данных с помощью Jdbctemplate : (RowCallbackHandlerResultSetExtractor.extractData)

#java #spring #spring-mvc #spring-data-jpa #jdbctemplate

#java #spring #spring-mvc #spring-data-jpa #jdbctemplate

Вопрос:

 public List<Employee> getEmployeeDataByDate(Date dateCreated) throws Exception {
        List<Employee> listDetails = new ArrayList<>();
        
        sqlServTemplate.query(SyncQueryConstants.RETRIEVE_EMPLOYEE_RECORDS_BY_DATE, new Object[] { dateCreated },
                new RowCallbackHandler() {

                    @Override
                    public void processRow(ResultSet rs) throws SQLException {
                        Employee emp = new Employee();
                        emp.setEmployeeID(rs.getString("employeeID"));
                        emp.setFirstName(rs.getString("firstName"));
                        emp.setLastName(rs.getString("lastName"));
                        emp.setMiddleName(rs.getString("middleName"));
                        emp.setNickName(rs.getString("nickName"));

                        byte[] res = rs.getBytes("employeeImage");
                        Blob blob = new SerialBlob(res);
                        emp.setEmployeeImage(blob);

                        
                        // .....
                        
                        listDetails.add(emp);
                    }
                    
        });
        
        return listDetails;
    }
  

Здесь я пытаюсь получить записи из таблицы employee.Из-за данных большого двоичного объекта он говорит OutOfMemoryError: пространство кучи Java . Может ли кто-нибудь помочь мне в этом?

Это отдельное приложение, я выполняю синхронизацию из одной таблицы в другую таблицу. Поэтому невозможно использовать разбивку на страницы. Каждый день запись 2k будет синхронизироваться в середине ночи с помощью задания cron. Дайте некоторое представление о том, как я могу решить эту проблему.

 SELECT * FROM Employees with(nolock) WHERE cast (datediff (day, 0, dateCreated) as datetime) >= ?
  

Этот запрос выдает мне все данные на основе даты (около 2 тыс. записей каждый день).
Если я комментирую

 byte[] res = rs.getBytes("employeeImage");
                        Blob blob = new SerialBlob(res);
                        emp.setEmployeeImage(blob);
  

Тогда эта строка не вызывает проблем. В противном случае это выдает ошибку.

Пожалуйста, дайте некоторую идею, если возможно, приведите несколько примеров кода. Я борюсь с 2 днями в этой возможности.

Комментарии:

1. И в чем вопрос? Слишком много данных, чтобы поместиться в доступное пространство кучи.

2. Увеличьте свою кучу или вы можете просто использовать разбивку на страницы и получить 100 записей за запрос

3. У меня есть другая таблица, в которой есть запись 4lakh, проблем нет. (Я также не использую разбивку на страницы) проблема возникает только в этой таблице.

4. Единственное различие, которое я нашел, заключается здесь в том, что для каждой записи, содержащей 120 полей, там всего 50 полей.

5. Поля BLOB / CLOB? Мое предположение: портретные фотографии размером с мегабайт. Проверьте, не используя все поля.

Ответ №1:

Как упоминали некоторые другие комментаторы, вы можете либо увеличить пространство кучи, либо ограничить количество записей, которые вы возвращаете из своего запроса, и обрабатывать их меньшими партиями.

Ответ №2:

Вы читаете изображение размером в МБ в байтах, оно будет потреблять вашу память КУЧИ .. вместо этого попробуйте использовать BinaryStream:

 InputStream image = rs.getBinaryStream("employeeImage");
  

Ответ №3:

Вместо того, чтобы добавлять каждого пользователя в список, вы могли бы обрабатывать их по одному. Помещайте каждую запись в другую базу данных по мере ее извлечения из исходной базы данных, а не добавляйте их в список, который вызывает ошибку ООМ. Если есть какая-то другая обработка ниже по потоку, тогда введите класс в этот DAO, который обрабатывает фактическую обработку / запись в целевую БД.